Строка в дату. Универсальное решение. Применение NetObjetToIDispatch45

Опубликовал invertercant в раздел Программирование - Инструментарий

Нам часто приходится делать преобразования строк в даты. В 1С нет специальных средств на эту тему. Более того, я не встречал никаких универсальных решений в 1С, которыми был бы доволен и в очередной раз нам приходится писать костыли вроде этого: Дата(Сред(стрДата,7,4)+Сред(стрДата,4,2)+Лев(стрДата,2)). Конечно же, в microsoft уже давно решили эту задачу на своей платформе NET. Почему мы бы им не воспользоваться.

I. Как сделать самому подобное. 

Хотелось бы не только решить конкретную задачу, но и показать, что пользоваться NET совсем не трудно.

Объемную статью Использование сборок .NET в 1с 7.x и 8.x по этому написал serginio. Я использую его наработки.

Вдохновившись знанием, что это реально, я начал поиски нужной функции.

Очень быстро гугл выдал DateTime.ParseExact.

Это статическая функция типа DateTime, которая проводит парсинг строки и возвращает дату. 

и примеры использования

Теперь о том, как это использовать в 1С.

1. Подключить ком-объект, позволяющий использовать функции NET 

БиблиотекаNET = новый COMОбъект("NetObjectToIDispatch45");

2. Создать тип DateTime

DateTime = БиблиотекаNET.ПолучитьТип("System.DateTime");

3. Вызвать функцию ParseExact

4. Параметры функции s и format примитивного типа, их можно передавать из 1С как есть

5. Параметры функции provider и style объектного типа. Их необходимо сначала создать.

6. Параметр style имеет тип DateTimeStyles. В описании пространство имен для него установлено System.Globalization.

Таким образом получить тип можно 

DataTimeStyles = БиблиотекаNET.ПолучитьТип("System.Globalization.DateTimeStyles");

DataTimeStyles  - перечисление и в описании определены его члены

Для того, чтобы передать параметр в функции, будем использовать член - DataTimeStyles.None

7.  Параметр provider имеет тип IFormatProvider.

Это интерфейс, его реализацию получили классы NumberFormatInfo, DateTimeFormatInfo и CultureInfo.

В примере вызова используется CultureInfo. Поступаем точно так же.

КлассCultureInfo = БиблиотекаNET.ПолучитьТип("System.Globalization.CultureInfo");
ОбъектCultureInfo = БиблиотекаNET.СоздатьОбъект(КлассCultureInfo, "ru-RU");

В итоге получаем

БиблиотекаNET = новый COMОбъект("NetObjectToIDispatch45");
DateTime = БиблиотекаNET.ПолучитьТип("System.DateTime");
КлассCultureInfo = БиблиотекаNET.ПолучитьТип("System.Globalization.CultureInfo");
ОбъектCultureInfo = БиблиотекаNET.СоздатьОбъект(КлассCultureInfo, "ru-Ru");
DataTimeStyles = БиблиотекаNET.ПолучитьТип("System.Globalization.DateTimeStyles");
Дата = DateTime.ParseExact
                    (
                    "10 февраля 1978",
                    "dd MMMM yyyy",
                    ОбъектCultureInfo,
                    DataTimeStyles.None
                    );

Для каждого региона есть стандартные шаблоны записи дат. Их можно посмотреть программой CultureInfoExplorer

Например, стандартные шаблоны дат для русского языка

Региональные настройки для русского языка

 

В обработке вместо рассмотренной функции используется TryParseExact и учитывается вариант без указания формата, а указания только региона.В этом случае произойдет перебор всех стандартных шаблонов описания дат для региона со скриншота от d до y. 

Результат после нажатия на кнопку "Пуск":

Конвертация строки в дату

 II. Как установить и начать пользоваться. 

1. Установить NET Framework 4.5 https://www.microsoft.com/ru-ru/download/details.aspx?id=30653
2. Регистрация NetObjetToIDispatch45.dll
2.1 Запустить РегистрацияКомСервера.exe
2.2 Нажать кнопку "Регистрация Сервера"
2.3 Выбрать файл NetObjetToIDispatch45.dll, после чего сгенерится строка вызова, необходимая для регистрации
2.4 Запустить командную строку от имени Администратора.
2.5 Скопировать строку вызова из формы в командную строку и запустить.
2.6 Убедиться, что результатом запуска стало "Типы зарегистрированы успешно"
3. Запустить обработку Универсальная_СтрокаВДату.epf
3.1 По нажатию кнопки "Пуск" все строки должны сконвертироваться в даты.

Файлы

Наименование Файл Версия Размер Кол. Скачив.
Универсальная_СтрокаВДату.zip
.zip 123,82Kb
17.12.15
4
.zip 123,82Kb 4 Скачать

См. также

Лучшие комментарии

5. Serginio 17.12.2015 10:11
(4) Во первых можно делать все на сервере. Во вторых какие проблемы с версиями и совместимостью? Если хочешь полную совместимость, то есть NetObjetToIDispatch для 2.0 используй её. А так с Win 7 обновление .Net framework

кстати актуальная версия 4.6.1

И зачем заного изобретать велосипед, когда все придумано давно
Ответили: (6)
+ 1 [ invertercant; ]
# Ответить

Комментарии

1. olbu 16.12.2015 10:07
Интересная статья. У меня возник вопрос, есть ли методы обойти "2. Регистрация NetObjetToIDispatch45.dll", те зарегистрировать dll не имея административных прав? У большинства пользователей нет административных прав...
Если это можно как то обойти, то можно использовать в работе.
Ответили: (2)
# Ответить
2. invertercant 16.12.2015 10:12
(1) olbu, Устанавливать это на каждой клиентской машине было бы странно. Лучше поставить на сервер и все функции использующие com объект, сделать серверными. На сервере права администратора все равно потребуются, но сделать это надо будет всего один раз.
# Ответить
3. Serginio 16.12.2015 16:44
В функции СоздатьОбъект можно передавать как строку так и тип. Например
КлассCultureInfo = БиблиотекаNET.ПолучитьТип("System.Globalization.CultureInfo");
ОбъектCultureInfo = БиблиотекаNET.СоздатьОбъект(КлассCultureInfo, "ru-Ru");

можно заменить одной строкой

ОбъектCultureInfo = БиблиотекаNET.СоздатьОбъект("System.Globalization.CultureInfo", "ru-Ru");

Вот описание функции

Type ТипДляСоздатьОбъект(object ТипOrig)
        {
            object Тип = ТипOrig;
            string ТипСтр = Тип.ToString();
            if (Тип is AutoWrap)
            { Тип = ((AutoWrap)Тип).O; }
            else if (Тип.GetType() == typeof(String))
            {

                Тип = НайтиТип((string)Тип);

                if (Тип == null)
                {
                    string ошибка = " неверный тип " + ТипСтр;
                    MessageBox.Show(ошибка);
                    throw new  COMException(ошибка);
                }
            }
            return (Type)Тип;
        }


public object СоздатьОбъект(object Тип, params object[] argOrig)
        {
            //   MessageBox.Show(Тип.ToString() + " параметров=" + args.Length.ToString());

            var res = ТипДляСоздатьОбъект(Тип);

            object[] args = AutoWrap.ПолучитьМассивРеальныхОбъектов(argOrig);
            return AutoWrap.ОбернутьОбъект(System.Activator.CreateInstance(res, args));

        }
...Показать Скрыть

Кстати нужно мне изменить с проверкой на ВыводитьСообщениеОбОшибке
# Ответить
4. gubanoff 17.12.2015 09:15
(0) Все супер, но внешние компоненты, определенные версии Net и тому подобное очень затруднительно использовать более, чем у одного клиента. Всегда возникают проблемы с совместимостью, что-то не установлено, что-то не той версии и т.п. Поэтому я бы взял все варианты дат для своего языка и обработал бы их в коде 1С. Плюс какие-то некорректные случаи. Но для общего развития полезный материал, спасибо.
Ответили: (5)
# Ответить
5. Serginio 17.12.2015 10:11
(4) Во первых можно делать все на сервере. Во вторых какие проблемы с версиями и совместимостью? Если хочешь полную совместимость, то есть NetObjetToIDispatch для 2.0 используй её. А так с Win 7 обновление .Net framework

кстати актуальная версия 4.6.1

И зачем заного изобретать велосипед, когда все придумано давно
Ответили: (6)
+ 1 [ invertercant; ]
# Ответить
6. gubanoff 17.12.2015 11:57
(5) Serginio, у каких-то клиентов Win XP, у каких-то Win 7, у каких-то и Linux может быть и еще много чего интересного.
# Ответить
7. Serginio 17.12.2015 13:09
Еще раз для Win XP есть NetObjetToIDispatch для 2.0 Ну а насчет Linux, то они ССЗБ.
# Ответить
8. Serginio 17.12.2015 13:15
И еще добавлю используя классы .Net для расширения возможностей 1С
1. Экономия времени, а значит и денег
2. Увеличение производительности
3. Замена ВК. Нужно умет программировать на 1С и знать классы .Net
# Ответить
9. Serginio 17.12.2015 15:56
(0) Может пример использования с Regex сделаешь? Уж больно у тебя все красиво
Ответили: (10)
# Ответить
10. invertercant 18.12.2015 14:28
(9) Serginio, Пусть лучше на эту тему знающий человек пишет. /(?:(?:\s*[+>~,]\s*|\s+)|[^:+>~,\s\\[\]]+(?:\\.[^:+>~,\s\\[\]]*)*)|\[(?:[^\\[\]]*(?:\\.[^\\[\]]*)*|[^=]+=~?\s*(?:"[^\\"]*(?:\\.[^"\\]*)*"|'[^\\']*(?:\\.[^'\\]*)*'))\]|:[^\\:([]+(?:\\.[^\\:([]*)*(?:\((?:[^\\()]*(?:\\.[^\\()]*)*|"[^\\"]*(?:\\.[^"\\]*)*"|'[^\\']*(?:\\.[^'\\]*)*')\))?/g Я к такому не готов. пока.
# Ответить
Внимание! За постинг в данном форуме $m не начисляются.
Внимание! Для написания сообщения необходимо авторизоваться
Текст сообщения*
Прикрепить файл






IE 2016