1
0
mirror of https://github.com/firstBitSportivnaya/PSSL.git synced 2024-11-21 17:56:47 +02:00

Изменена загрузка файла из табличного документа (#130)

* Изменена загрузка файла из табличного документа
* Добавлено направление потока
* Доработано взаимодействие с ВИД

Closes #76 #100 #126 #131
This commit is contained in:
Permichev Vladislav 2024-10-23 18:37:24 +03:00 committed by GitHub
parent 1cc3e8255a
commit 8762df67af
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
21 changed files with 1254 additions and 281 deletions

View File

@ -321,6 +321,46 @@
<DataHistory>Use</DataHistory>
</Properties>
</Attribute>
<Attribute uuid="32a4dc86-bf2c-4272-a5b5-98b253538ea5">
<Properties>
<Name>НаправлениеПотока</Name>
<Synonym>
<v8:item>
<v8:lang>ru</v8:lang>
<v8:content>Направление потока</v8:content>
</v8:item>
</Synonym>
<Comment/>
<Type>
<v8:Type>cfg:EnumRef.пбп_НаправленияИнтеграционныхПотоков</v8:Type>
</Type>
<PasswordMode>false</PasswordMode>
<Format/>
<EditFormat/>
<ToolTip/>
<MarkNegatives>false</MarkNegatives>
<Mask/>
<MultiLine>false</MultiLine>
<ExtendedEdit>false</ExtendedEdit>
<MinValue xsi:nil="true"/>
<MaxValue xsi:nil="true"/>
<FillFromFillingValue>false</FillFromFillingValue>
<FillValue xsi:nil="true"/>
<FillChecking>ShowError</FillChecking>
<ChoiceFoldersAndItems>Items</ChoiceFoldersAndItems>
<ChoiceParameterLinks/>
<ChoiceParameters/>
<QuickChoice>Auto</QuickChoice>
<CreateOnInput>Auto</CreateOnInput>
<ChoiceForm/>
<LinkByType/>
<ChoiceHistoryOnInput>Auto</ChoiceHistoryOnInput>
<Use>ForItem</Use>
<Indexing>DontIndex</Indexing>
<FullTextSearch>Use</FullTextSearch>
<DataHistory>Use</DataHistory>
</Properties>
</Attribute>
<TabularSection uuid="2a6450ad-2f8e-4dab-bdcb-6a6acaf132f9">
<InternalInfo>
<xr:GeneratedType name="CatalogTabularSection.пбп_ИнтеграционныеПотоки.ПараметрыВхода" category="TabularSection">

View File

@ -88,6 +88,12 @@
<Event name="StartChoice">НастройкаИнтеграцииНачалоВыбора</Event>
</Events>
</InputField>
<InputField name="НаправлениеПотока" id="59">
<DataPath>Объект.НаправлениеПотока</DataPath>
<ExtendedEditMultipleValues>true</ExtendedEditMultipleValues>
<ContextMenu name="НаправлениеПотокаКонтекстноеМеню" id="60"/>
<ExtendedTooltip name="НаправлениеПотокаРасширеннаяПодсказка" id="61"/>
</InputField>
<InputField name="ПользовательскаяФункция" id="40">
<DataPath>Объект.ПользовательскаяФункция</DataPath>
<ExtendedEditMultipleValues>true</ExtendedEditMultipleValues>

View File

@ -304,6 +304,7 @@
<v8:content>Группа данные сообщения исходящего</v8:content>
</v8:item>
</ToolTip>
<Behavior>Usual</Behavior>
<Representation>None</Representation>
<ShowTitle>false</ShowTitle>
<ExtendedTooltip name="ГруппаДанныеСообщенияИсходящегоРасширеннаяПодсказка" id="164"/>
@ -367,6 +368,7 @@
<v8:content>Группа данные сообщения исходящего</v8:content>
</v8:item>
</ToolTip>
<Behavior>Usual</Behavior>
<Representation>None</Representation>
<ShowTitle>false</ShowTitle>
<ExtendedTooltip name="ГруппаДанныеСообщенияВходящегоРасширеннаяПодсказка" id="166"/>

View File

@ -279,7 +279,9 @@
Функция НаправлениеИнтеграцииВыгружено(СтатусОбмена)
Возврат СтатусОбмена = Перечисления.пбп_СтатусыИнтеграции.Выгружено
Или СтатусОбмена = Перечисления.пбп_СтатусыИнтеграции.ОшибкаВыгрузки;
Или СтатусОбмена = Перечисления.пбп_СтатусыИнтеграции.ОшибкаВыгрузки
Или СтатусОбмена = Перечисления.пбп_СтатусыИнтеграции.Служебный
Или СтатусОбмена = Перечисления.пбп_СтатусыИнтеграции.ОшибкаСлужебного;
КонецФункции

View File

@ -27,225 +27,30 @@
// Параметры:
// АдресВХранилище - Строка - Адрес файла во временном хранилище
// Расширение - Строка - Расширение файла (xls, xlsx)
// Параметры - Структура - Параметры загрузки
// Параметры - Структура - структура параметров загрузки Excel-файла
// см. пбп_ЗагрузкаФайлаЧерезТабличныйДокументКлиент.ИнициализироватьСтруктуруПередачиПараметровНаСервер
//
Процедура ФормированиеТаблицы(АдресВХранилище, Расширение, Параметры) Экспорт
Макет = Параметры.Макет;
АдресПомещения = Параметры.АдресПомещения;
НазваниеЛиста = Параметры.НазваниеЛиста;
НомерСтроки = Параметры.НомерПервойСтроки;
ТаблицаСвойств = ПолучитьИзВременногоХранилища(Параметры.АдресМакета);
ДвоичныеДанные = ПолучитьИзВременногоХранилища(АдресВХранилище);
ИмяВременногоФайла = ПолучитьИмяВременногоФайла(Расширение);
ДвоичныеДанные.Записать(ИмяВременногоФайла);
ПараметрыЧтения = пбп_ЗагрузкаФайлаЧерезТабличныйДокументСервер.ПолучитьПараметрыЧтенияФайла();
ПараметрыЧтения.НазваниеЛиста = Параметры.НазваниеЛиста;
ПараметрыЧтения.НомерСтроки = Параметры.НомерПервойСтроки;
ПараметрыЧтения.СопоставлениеПоНаименованию = Параметры.ПоНаименованию;
ТабДок = Новый ТабличныйДокумент;
ТабДок.Прочитать(ИмяВременногоФайла, СпособЧтенияЗначенийТабличногоДокумента.Текст);
ТаблицаДанных = пбп_ЗагрузкаФайлаЧерезТабличныйДокументСервер
.КонвертироватьДанныеТабличногоДокументаВТаблицуЗначений(
АдресВХранилище, Расширение, ТаблицаСвойств, ПараметрыЧтения);
Попытка
УдалитьФайлы(ИмяВременногоФайла);
Исключение
ЗаписьЖурналаРегистрации(НСтр("ru = 'Загрузка файла через табличный документ.Удаление временного файла'"), УровеньЖурналаРегистрации.Ошибка, , , ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;
Лист = ?(ЗначениеЗаполнено(НазваниеЛиста), Табдок.Области.Найти(СтрЗаменить(НазваниеЛиста, " ", "_")), Неопределено);
ПервыйЛист = ТабДок.Области[0].Имя;
Для Каждого ЛистДок Из ТабДок.Области Цикл
Если ЛистДок.Верх = 1 Тогда
ПервыйЛист = ЛистДок.Имя;
КонецЕсли;
КонецЦикла;
ТабДок = ТабДок.ПолучитьОбласть(?(Лист = Неопределено, ПервыйЛист, СтрЗаменить(НазваниеЛиста, " ", "_")));
Если Не НомерСтроки = 1 Тогда
ТабДок.УдалитьОбласть(ТабДок.Область("R1:R" + Строка(НомерСтроки - 1)), ТипСмещенияТабличногоДокумента.ПоВертикали);
КонецЕсли;
ТабДок.ВставитьОбласть(ТабДок.Область("R1"),
ТабДок.Область("R1"),
ТипСмещенияТабличногоДокумента.ПоГоризонтали);
Табдок.Область("R1").Очистить(Истина, Истина, Истина);
Счетчик = 0;
Для Каждого Колонка Из Макет Цикл
Счетчик = Счетчик + 1;
Если Не ЗначениеЗаполнено(Колонка.Значение) Тогда
Продолжить;
КонецЕсли;
ТабДок.Область("R1" + "C" + Строка(Счетчик)).Текст = Колонка.Ключ;
КонецЦикла;
ПЗ = Новый ПостроительЗапроса;
ПЗ.ИсточникДанных = Новый ОписаниеИсточникаДанных(ТабДок.Область());
ПЗ.ДобавлениеПредставлений = ТипДобавленияПредставлений.Добавлять;
ПЗ.ЗаполнитьНастройки();
ПЗ.Выполнить();
ТЗ = ПЗ.Результат.Выгрузить();
ТЗ.Колонки.Добавить("ПорядковыйНомер", Новый ОписаниеТипов("Число"));
КоллекцияОтборов = Новый ТаблицаЗначений;
КоллекцияОтборов.Колонки.Добавить("ТипДанных");
КоллекцияОтборов.Колонки.Добавить("НомерСтрокиДочерней");
КоллекцияОтборов.Колонки.Добавить("МассивДанных");
КоллекцияОтборов.Колонки.Добавить("НазваниеКолонки");
Н = ТЗ.Количество() - 1;
Пока НЕ Н < 0 Цикл
Счетчик = 0;
ТЗ[Н].ПорядковыйНомер = Н;
Для каждого Колонка Из ТЗ.Колонки Цикл
Если Не ЗначениеЗаполнено(ТЗ[Н][Колонка.Имя]) Тогда
Счетчик = Счетчик + 1;
КонецЕсли;
КонецЦикла;
Если Счетчик = ТЗ.Колонки.Количество() Тогда
ТЗ.Удалить(Н);
КонецЕсли;
Н = Н - 1;
КонецЦикла;
ВставкаВТ = "";
ВставкаБазовые = "";
ВставкаСсылочные = "";
ВставкаИсточники = "";
ХранилищеИсточников = Новый Соответствие;
МассивИменСсылочных = Новый Массив;
СоответствиеПеречислений = Новый Соответствие;
Для Каждого Колонка Из Макет Цикл
Если Не ЗначениеЗаполнено(Колонка.Значение) Тогда
Продолжить;
КонецЕсли;
ВставкаВТ = ВставкаВТ + "ВходнаяТаблица." + Колонка.Ключ + " КАК " + Колонка.Ключ + "," + Символы.ПС;
Если СтрНайти(Колонка.Значение, "Ссылка") <> 0 И СтрНайти(Колонка.Значение, "Перечисление") = 0 Тогда
ТЗ.Колонки.Добавить(Колонка.Ключ + "КодЧислом", Новый ОписаниеТипов("Число", , , Новый КвалификаторыЧисла(15)));
ВставкаВТ = ВставкаВТ + "ВходнаяТаблица." + Колонка.Ключ + "КодЧислом КАК " + Колонка.Ключ + "КодЧислом," + Символы.ПС;
МассивИменСсылочных.Добавить(Колонка.Ключ);
РазбивкаТипа = СтрРазделить(СтрЗаменить(Колонка.Значение, "Ссылка", ""), ".", Ложь);
ВхождениеИсточника = ХранилищеИсточников.Получить(РазбивкаТипа[1]);
ХранилищеИсточников.Вставить(РазбивкаТипа[1], ?(ВхождениеИсточника = Неопределено, 1, ВхождениеИсточника + 1));
Итерация = ?(ХранилищеИсточников.Получить(РазбивкаТипа[1]) = 0, "", Строка(ХранилищеИсточников.Получить(РазбивкаТипа[1])));
Если РазбивкаТипа[0] = "Документ" Тогда
РеквизитСравнения = "Номер";
Иначе
РеквизитСравнения = "Наименование";
КонецЕсли;
ВставкаСсылочные = ВставкаСсылочные + РазбивкаТипа[1] + Итерация + ".Ссылка КАК " + Колонка.Ключ + "," + Символы.ПС;
Если Не СтрНайти(ВставкаИсточники, " " + РазбивкаТипа[1] + " ") > 0 Тогда
ВставкаИсточники = ВставкаИсточники + "
| ЛЕВОЕ СОЕДИНЕНИЕ " + СтрЗаменить(Колонка.Значение, "Ссылка", "") + " КАК " + РазбивкаТипа[1] + Итерация + "
| ПО " + "ВходнаяТаблица." + Колонка.Ключ + " <> """" И " + "ВходнаяТаблица." + Колонка.Ключ + " <> 0" + "
| И (ВходнаяТаблица." + Колонка.Ключ + " = " + РазбивкаТипа[1] + Итерация + "." + РеквизитСравнения + Символы.ПС;
Если СтрНайти(РазбивкаТипа[1], "Номенклатура") > 0 Тогда
ВставкаИсточники = ВставкаИсточники + " ИЛИ "
+ "ВходнаяТаблица." + Колонка.Ключ + " = " + РазбивкаТипа[1] + Итерация + "." + "Артикул" + Символы.ПС;
ВставкаИсточники = ВставкаИсточники + " ИЛИ "
+ "ВходнаяТаблица." + Колонка.Ключ + "КодЧислом = " + РазбивкаТипа[1] + Итерация + "." + "Код" + Символы.ПС;
ВставкаИсточники = ВставкаИсточники + " ИЛИ "
+ "ВходнаяТаблица." + Колонка.Ключ + " = " + РазбивкаТипа[1] + Итерация + "." + "Код" + Символы.ПС;
ИначеЕсли СтрНайти(Колонка.Значение, "Справочник") > 0
И Не СтрНайти(Колонка.Значение, "Организации") > 0 Тогда
ВставкаИсточники = ВставкаИсточники + " ИЛИ "
+ "ВходнаяТаблица." + Колонка.Ключ + "КодЧислом = " + РазбивкаТипа[1] + Итерация + "." + "Код" + Символы.ПС;
ВставкаИсточники = ВставкаИсточники + " ИЛИ "
+ "ВходнаяТаблица." + Колонка.Ключ + " = " + РазбивкаТипа[1] + Итерация + "." + "Код" + Символы.ПС;
КонецЕсли;
ВставкаБазовые = ВставкаБазовые + "ВходнаяТаблица." + Колонка.Ключ + " КАК " + Колонка.Ключ + "Служебный," + Символы.ПС;
ВставкаИсточники = ВставкаИсточники + ")";
КонецЕсли;
ИначеЕсли СтрНайти(Колонка.Значение, "Перечисление") <> 0 Тогда
КолонкаПеречисления = ТЗ.Колонки.Добавить(Колонка.Ключ + "НеОбрабатывать", Новый ОписаниеТипов(Колонка.Значение));
СоответствиеПеречислений.Вставить(Колонка.Ключ, Колонка.Значение);
ВставкаВТ = СтрЗаменить(ВставкаВТ, "." + Колонка.Ключ + " КАК", "." + КолонкаПеречисления.Имя + " КАК");
ВставкаБазовые = ВставкаБазовые + "ВходнаяТаблица." + Колонка.Ключ + " КАК " + Колонка.Ключ + "," + Символы.ПС;
ИначеЕсли Не СтрНайти(Колонка.Ключ, "НеОбрабатывать") > 0 Тогда
ВставкаБазовые = ВставкаБазовые + "ВходнаяТаблица." + Колонка.Ключ + " КАК " + Колонка.Ключ + "," + Символы.ПС;
КонецЕсли;
КонецЦикла;
ВставкаВТ = ВставкаВТ + "ВходнаяТаблица.ПорядковыйНомер Как ПорядковыйНомер";
ВставкаБазовые = Лев(ВставкаБазовые, СтрДлина(ВставкаБазовые) - 2);
ОТЧ = Новый ОписаниеТипов("Число", , , Новый КвалификаторыЧисла(15));
Для Каждого СтрокаТаблицы Из ТЗ Цикл
Для Каждого ИмяМассива Из МассивИменСсылочных Цикл
СтрокаТаблицы[ИмяМассива + "КодЧислом"] = ОТЧ.ПривестиЗначение(СтрокаТаблицы[ИмяМассива]);
КонецЦикла;
Для Каждого Колонка Из СоответствиеПеречислений Цикл
Для Каждого ТекЭлемент Из Метаданные.Перечисления[СтрЗаменить(Колонка.Значение, "ПеречислениеСсылка.", "")].ЗначенияПеречисления Цикл
Если нРег(ТекЭлемент.Синоним) = нРег(СтрокаТаблицы[Колонка.Ключ]) Тогда
СтрокаТаблицы[Колонка.Ключ + "НеОбрабатывать"] = Перечисления[СтрЗаменить(Колонка.Значение, "ПеречислениеСсылка.", "")][ТекЭлемент.Имя];
Прервать;
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецЦикла;
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| #ВставкаВТ
|ПОМЕСТИТЬ ВходнаяТаблица
|ИЗ
| &ВходнаяТаблица КАК ВходнаяТаблица
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| #ВставкаСсылочные
| #ВставкаБазовые
|ИЗ
| ВходнаяТаблица КАК ВходнаяТаблица
| #ВставкаИсточники
|
|УПОРЯДОЧИТЬ ПО
| ВходнаяТаблица.ПорядковыйНомер";
Запрос.Текст = СтрЗаменить(Запрос.Текст, "#ВставкаВТ", ВставкаВТ);
Запрос.Текст = СтрЗаменить(Запрос.Текст, "#ВставкаСсылочные", ВставкаСсылочные);
Запрос.Текст = СтрЗаменить(Запрос.Текст, "#ВставкаБазовые", ВставкаБазовые);
Запрос.Текст = СтрЗаменить(Запрос.Текст, "#ВставкаИсточники", ВставкаИсточники);
Запрос.УстановитьПараметр("ВходнаяТаблица", ТЗ);
РезультатЗапроса = Запрос.Выполнить();
ПоместитьВоВременноеХранилище(РезультатЗапроса.Выгрузить(), АдресПомещения);
ПоместитьВоВременноеХранилище(ТаблицаДанных, Параметры.АдресПомещения);
КонецПроцедуры
// Функция - Поместить заглушку
//
// Параметры:
// Макет - Структура - Список колонок загружаемого файла
// Макет - Строка - Адрес временного хранилища, где находится таблица значений со списком колонок загружаемого файла
//
// Возвращаемое значение:
// - Строка - Адрес файла во временном хранилище
@ -254,8 +59,10 @@
Заглушка = Новый ТаблицаЗначений;
Для Каждого Колонка Из Макет Цикл
Заглушка.Колонки.Добавить(Колонка.Ключ, Новый ОписаниеТипов(Колонка.Значение));
МакетТаблица = ПолучитьИзВременногоХранилища(Макет);
Для Каждого КолонкаТаблицы Из МакетТаблица Цикл
Заглушка.Колонки.Добавить(КолонкаТаблицы.ИмяКолонки, Новый ОписаниеТипов(КолонкаТаблицы.ТипЗначения));
КонецЦикла;
ИД = ПоместитьВоВременноеХранилище(Заглушка, Новый УникальныйИдентификатор);
@ -264,4 +71,27 @@
КонецФункции
#КонецОбласти
// Инициализирует таблицу со свойствами колонок загружаемого файла
//
// Возвращаемое значение:
// ТаблицаЗначений - таблица готовая для заполнения данных колонок
//
Функция ИнициализироватьТаблицуСоСвойствамиКолонок() Экспорт
СвойстваКолонок = Новый ТаблицаЗначений;
ДлинаСтроки = 150;
СвойстваКолонок.Колонки.Добавить("ИмяКолонки" , пбп_ОбщегоНазначенияСервер.ОписаниеТипаСтрока(ДлинаСтроки));
СвойстваКолонок.Колонки.Добавить("ИмяВТабДоке" , пбп_ОбщегоНазначенияСервер.ОписаниеТипаСтрока(ДлинаСтроки));
СвойстваКолонок.Колонки.Добавить("ТипЗначения" , пбп_ОбщегоНазначенияСервер.ОписаниеТипаСтрока(ДлинаСтроки));
СвойстваКолонок.Колонки.Добавить("ПолеПоиска1" , пбп_ОбщегоНазначенияСервер.ОписаниеТипаСтрока(ДлинаСтроки));
СвойстваКолонок.Колонки.Добавить("ПолеПоиска2" , пбп_ОбщегоНазначенияСервер.ОписаниеТипаСтрока(ДлинаСтроки));
СвойстваКолонок.Колонки.Добавить("ПолеПоиска3" , пбп_ОбщегоНазначенияСервер.ОписаниеТипаСтрока(ДлинаСтроки));
// BSLLS:MagicNumber-off
СвойстваКолонок.Колонки.Добавить("ОператорСравнения" , пбп_ОбщегоНазначенияСервер.ОписаниеТипаСтрока(3));
// BSLLS:MagicNumber-on
Возврат СвойстваКолонок;
КонецФункции
#КонецОбласти // ПрограммныйИнтерфейс

View File

@ -22,21 +22,31 @@
#Область ПрограммныйИнтерфейс
// Функция - Загрузить из XLS
// Загружает файл XLS, парсит его и помещает результат в таблицу значений, которая передается во временное хранилище
//
// Параметры:
// СоответствиеКолонок - Структура - Описание колонок загружаемого файла
// НазваниеЛиста - Строка - Имя загружаемого листа (по-умолчанию не заполнено)
// НомерПервойСтроки - Число - Номер строки с которой начинается загрузка данных (по-умолчанию 1)
// АдресСоответствияКолонок - Строка - описание колонок загружаемого файла в таблице значений,
// помещенное во временное хранилище на Сервере.
// см. пбп_ЗагрузкаФайлаЧерезТабличныйДокументВызовСервера.ИнициализироватьТаблицуСоСвойствамиКолонок
// НазваниеЛиста - Строка - Имя загружаемого листа (по-умолчанию не заполнено)
// НомерПервойСтроки - Число - Номер строки с которой начинается загрузка данных (по-умолчанию 1)
// СопоставлениеПоНаименованию - Булево - если Истина, то колонки макета сопоставляются с табличным документом по
// наименованию; если Ложь, то сопоставляются в последовательности колонок макета, а наименования игнорируются.
//
// Возвращаемое значение:
// - Строка - Адрес файла во временном хранилище
// Строка - Адрес файла во временном хранилище
//
Асинх Функция ЗагрузитьИзXLS(СоответствиеКолонок, НазваниеЛиста = "", НомерПервойСтроки = 1) Экспорт
Асинх Функция ЗагрузитьИзXLS(АдресСоответствияКолонок,НазваниеЛиста = "",
НомерПервойСтроки = 1, СопоставлениеПоНаименованию = Ложь) Экспорт
АдресПомещения = пбп_ЗагрузкаФайлаЧерезТабличныйДокументВызовСервера.ПоместитьЗаглушку(СоответствиеКолонок);
АдресПомещения = пбп_ЗагрузкаФайлаЧерезТабличныйДокументВызовСервера.ПоместитьЗаглушку(АдресСоответствияКолонок);
Параметры = Новый Структура("Макет, АдресПомещения, НазваниеЛиста, НомерПервойСтроки", СоответствиеКолонок, АдресПомещения, НазваниеЛиста, НомерПервойСтроки);
Параметры = ИнициализироватьСтруктуруПередачиПараметровНаСервер();
Параметры.АдресМакета = АдресСоответствияКолонок;
Параметры.АдресПомещения = АдресПомещения;
Параметры.НазваниеЛиста = НазваниеЛиста;
Параметры.НомерПервойСтроки = НомерПервойСтроки;
Параметры.ПоНаименованию = СопоставлениеПоНаименованию;
ПараметрыДиалога = Новый ПараметрыДиалогаПомещенияФайлов;
ПараметрыДиалога.Фильтр = "Документ Excel (*.xls, *.xlsx)|*.xls;*.xlsx|";
@ -47,7 +57,8 @@
ОписаниеФайла = Ждать ПоместитьФайлНаСерверАсинх( , , , ПараметрыДиалога);
Если ТипЗнч(ОписаниеФайла) = Тип("ОписаниеПомещенногоФайла") И Не ОписаниеФайла.ПомещениеФайлаОтменено Тогда
пбп_ЗагрузкаФайлаЧерезТабличныйДокументВызовСервера.ФормированиеТаблицы(ОписаниеФайла.Адрес, ОписаниеФайла.СсылкаНаФайл.Расширение, Параметры);
пбп_ЗагрузкаФайлаЧерезТабличныйДокументВызовСервера.ФормированиеТаблицы(
ОписаниеФайла.Адрес, ОписаниеФайла.СсылкаНаФайл.Расширение, Параметры);
Иначе
пбп_ОбщегоНазначенияСлужебныйКлиент.СообщитьПользователю(НСтр("ru = 'Помещение файла отменено'"));
АдресПомещения = Неопределено;
@ -57,4 +68,17 @@
КонецФункции
#КонецОбласти
#КонецОбласти // ПрограммныйИнтерфейс
#Область СлужебныеПроцедурыИФункции
Функция ИнициализироватьСтруктуруПередачиПараметровНаСервер()
СтруктураПараметров = Новый Структура(
"АдресМакета, АдресПомещения, НазваниеЛиста, НомерПервойСтроки, ПоНаименованию");
Возврат СтруктураПараметров;
КонецФункции
#КонецОбласти // СлужебныеПроцедурыИФункции

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<MetaDataObject xmlns="http://v8.1c.ru/8.3/MDClasses" xmlns:app="http://v8.1c.ru/8.2/managed-application/core" xmlns:cfg="http://v8.1c.ru/8.1/data/enterprise/current-config" xmlns:cmi="http://v8.1c.ru/8.2/managed-application/cmi" xmlns:ent="http://v8.1c.ru/8.1/data/enterprise" xmlns:lf="http://v8.1c.ru/8.2/managed-application/logform" xmlns:style="http://v8.1c.ru/8.1/data/ui/style" xmlns:sys="http://v8.1c.ru/8.1/data/ui/fonts/system" xmlns:v8="http://v8.1c.ru/8.1/data/core" xmlns:v8ui="http://v8.1c.ru/8.1/data/ui" xmlns:web="http://v8.1c.ru/8.1/data/ui/colors/web" xmlns:win="http://v8.1c.ru/8.1/data/ui/colors/windows" xmlns:xen="http://v8.1c.ru/8.3/xcf/enums" xmlns:xpr="http://v8.1c.ru/8.3/xcf/predef" xmlns:xr="http://v8.1c.ru/8.3/xcf/readable" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.16">
<CommonModule uuid="ca6de14a-47ae-4468-92da-b9e6cdb71e64">
<Properties>
<Name>пбп_ЗагрузкаФайлаЧерезТабличныйДокументСервер</Name>
<Synonym>
<v8:item>
<v8:lang>ru</v8:lang>
<v8:content>Загрузка файла через табличный документ сервер</v8:content>
</v8:item>
</Synonym>
<Comment/>
<Global>false</Global>
<ClientManagedApplication>false</ClientManagedApplication>
<Server>true</Server>
<ExternalConnection>true</ExternalConnection>
<ClientOrdinaryApplication>false</ClientOrdinaryApplication>
<ServerCall>false</ServerCall>
<Privileged>false</Privileged>
<ReturnValuesReuse>DontUse</ReturnValuesReuse>
</Properties>
</CommonModule>
</MetaDataObject>

View File

@ -0,0 +1,704 @@
// Библиотека проектных подсистем для упрощения разработки архитектуры на 1С: Предприятие 8,
// включая доработку типовых конфигураций.
//
// Copyright First BIT company
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// URL: https://github.com/firstBitSportivnaya/PSSL/
//
#Область ПрограммныйИнтерфейс
// Получить параметры чтения файла
// - НазваниеЛиста - Строка - наименование листа, с которого необходимо выполнить загрузку данных
// - НомерСтроки - Число - номер первой строки листа, с которой начинается парсинг данных
// - СопоставлениеПоНаименованию - Булево - если Истина, то колонки макета сопоставляются с табличным документом по
// наименованию; если Ложь, то сопоставляются в последовательности колонок макета, а наименования игнорируются.
// - КонвертироватьДаты - Булево - конвертировать значения с типом дата из строки в дату
//
// Возвращаемое значение:
// Структура - параметры чтения
//
Функция ПолучитьПараметрыЧтенияФайла() Экспорт
ПараметрыЧтения = Новый Структура;
ПараметрыЧтения.Вставить("НазваниеЛиста", "");
ПараметрыЧтения.Вставить("НомерСтроки", 0);
ПараметрыЧтения.Вставить("СопоставлениеПоНаименованию", Ложь);
ПараметрыЧтения.Вставить("КонвертироватьДаты", Истина);
Возврат ПараметрыЧтения;
КонецФункции
// Конвертирует данные табличного документа в таблицу значений по переданному макету
//
// Параметры:
// АдресВХранилище - Строка - Адрес файла во временном хранилище
// Расширение - Строка - Расширение файла (xls, xlsx)
// Макет - ТаблицаЗначений - в таблице указано имя колонок, их тип и поле поиска ссылочного типа
// ПараметрыЧтения - Структура - см. ПолучитьПараметрыЧтенияФайла
//
// Возвращаемое значение:
// ТаблицаЗначений - таблица с данными файла
//
Функция КонвертироватьДанныеТабличногоДокументаВТаблицуЗначений(
АдресВХранилище, Расширение, Макет, ПараметрыЧтения) Экспорт
НазваниеЛиста = ПараметрыЧтения.НазваниеЛиста;
НомерСтроки = ПараметрыЧтения.НомерСтроки;
СопоставлениеПоНаименованию = ПараметрыЧтения.СопоставлениеПоНаименованию;
КонвертироватьДаты = ПараметрыЧтения.КонвертироватьДаты;
ДвоичныеДанные = ПолучитьИзВременногоХранилища(АдресВХранилище);
ИмяВременногоФайла = ПолучитьИмяВременногоФайла(Расширение);
ДвоичныеДанные.Записать(ИмяВременногоФайла);
ТабДок = Новый ТабличныйДокумент;
ТабДок.Прочитать(ИмяВременногоФайла, СпособЧтенияЗначенийТабличногоДокумента.Текст);
Попытка
// BSLLS:UsingSynchronousCalls-off
УдалитьФайлы(ИмяВременногоФайла);
// BSLLS:UsingSynchronousCalls-on
Исключение
ТекстОшибки = НСтр("ru = 'Загрузка файла через табличный документ.Удаление временного файла'");
ЗаписьЖурналаРегистрации(ТекстОшибки,
УровеньЖурналаРегистрации.Ошибка, , ,
ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;
Лист = ?(ЗначениеЗаполнено(НазваниеЛиста), Табдок.Области.Найти(СтрЗаменить(НазваниеЛиста, " ", "_")), Неопределено);
ПервыйЛист = ТабДок.Области[0].Имя;
Для Каждого ЛистДок Из ТабДок.Области Цикл
Если ЛистДок.Верх = 1 Тогда
ПервыйЛист = ЛистДок.Имя;
КонецЕсли;
КонецЦикла;
ТабДок = ТабДок.ПолучитьОбласть(?(Лист = Неопределено, ПервыйЛист, СтрЗаменить(НазваниеЛиста, " ", "_")));
ТЗ = ПолучитьПромежуточнуюТаблицуЗначенийИзТабличногоДокумента(
ТабДок, НомерСтроки, Макет, СопоставлениеПоНаименованию);
КоллекцияОтборов = Новый ТаблицаЗначений;
КоллекцияОтборов.Колонки.Добавить("ТипДанных");
КоллекцияОтборов.Колонки.Добавить("НомерСтрокиДочерней");
КоллекцияОтборов.Колонки.Добавить("МассивДанных");
КоллекцияОтборов.Колонки.Добавить("НазваниеКолонки");
Н = ТЗ.Количество() - 1;
Пока Не Н < 0 Цикл
Счетчик = 0;
ТЗ[Н].ПорядковыйНомер = Н;
Для Каждого Колонка Из ТЗ.Колонки Цикл
Если Не ЗначениеЗаполнено(ТЗ[Н][Колонка.Имя]) Тогда
Счетчик = Счетчик + 1;
КонецЕсли;
КонецЦикла;
Если Счетчик = ТЗ.Колонки.Количество() Тогда
ТЗ.Удалить(Н);
КонецЕсли;
Н = Н - 1;
КонецЦикла;
ВставкаВТ = "";
ВставкаБазовые = "";
ВставкаСсылочные = "";
ВставкаИсточники = "";
ХранилищеИсточников = Новый Соответствие;
МассивИменСсылочных = Новый Массив;
СтруктураИменКолонокДат = Новый Структура;
СоответствиеПеречислений = Новый Соответствие;
ДлинаЧисла = 15;
ОписаниеТипаЧисло15 = Новый ОписаниеТипов("Число", , , Новый КвалификаторыЧисла(ДлинаЧисла));
ШаблонИмяКолонки = "ВходнаяТаблица.%1 КАК %1," + Символы.ПС;
СтрокаНеОбрабатывать = "НеОбрабатывать";
СсылкаСтрока = "Ссылка";
КодЧисломСтрока = "КодЧислом";
ВходнаяТаблицаСтрока = "ВходнаяТаблица.";
Для Каждого СтрокаТаблицы Из Макет Цикл
Если Не ЗначениеЗаполнено(СтрокаТаблицы.ТипЗначения) Тогда
Продолжить;
КонецЕсли;
ВставкаВТ = ВставкаВТ + СтрШаблон(ШаблонИмяКолонки, СтрокаТаблицы.ИмяКолонки);
Если СтрНайти(СтрокаТаблицы.ТипЗначения, СсылкаСтрока) <> 0
И СтрНайти(СтрокаТаблицы.ТипЗначения, "Перечисление") = 0 Тогда
ТЗ.Колонки.Добавить(СтрокаТаблицы.ИмяКолонки + КодЧисломСтрока, ОписаниеТипаЧисло15);
ВставкаВТ = ВставкаВТ + СтрШаблон(ШаблонИмяКолонки, СтрокаТаблицы.ИмяКолонки + КодЧисломСтрока);
МассивИменСсылочных.Добавить(СтрокаТаблицы.ИмяКолонки);
РазбивкаТипа = СтрРазделить(СтрЗаменить(СтрокаТаблицы.ТипЗначения, СсылкаСтрока, ""), ".", Ложь);
ИмяОбъекта = РазбивкаТипа[1];
ВхождениеИсточника = ХранилищеИсточников.Получить(ИмяОбъекта);
ХранилищеИсточников.Вставить(ИмяОбъекта, ?(ВхождениеИсточника = Неопределено, 1, ВхождениеИсточника + 1));
Итерация = ?(ХранилищеИсточников.Получить(ИмяОбъекта) = 0, "", Строка(ХранилищеИсточников.Получить(ИмяОбъекта)));
// В макете могут быть заявлены поля, для которых не назначили полей поиска
ЕстьПоляПоиска = ЗначениеЗаполнено(СтрокаТаблицы.ПолеПоиска1)
Или ЗначениеЗаполнено(СтрокаТаблицы.ПолеПоиска2)
Или ЗначениеЗаполнено(СтрокаТаблицы.ПолеПоиска3);
Если ЕстьПоляПоиска Тогда
ВставкаСсылочные = ВставкаСсылочные + ИмяОбъекта + Итерация
+ ".Ссылка КАК " + СтрокаТаблицы.ИмяКолонки + "," + Символы.ПС;
Иначе
ВставкаСсылочные = ВставкаСсылочные + "НЕОПРЕДЕЛЕНО КАК "
+ СтрокаТаблицы.ИмяКолонки + "," + Символы.ПС;
КонецЕсли;
ОператорСравнения = ?(ПустаяСтрока(СтрокаТаблицы.ОператорСравнения),
"ИЛИ", СтрокаТаблицы.ОператорСравнения);
Если Не СтрНайти(ВставкаИсточники, " " + ИмяОбъекта + " ") > 0 И ЕстьПоляПоиска Тогда
ВставкаУсловияСоединения = "";
Для Инкремент = 1 По 3 Цикл
РеквизитСравнения = СтрокаТаблицы["ПолеПоиска" + Инкремент];
Если ПустаяСтрока(РеквизитСравнения) Тогда
Продолжить;
КонецЕсли;
// Возможно использование оператора И для сопоставления, но при его использовании
// имена полей поиска должны равняться именам колонок обрабатываемой таблицы. Например:
// Если в свойствах макета у колонки заполнен тип ДокументСсылка., ПолеПоиска1 = "Номер",
// а ПолеПоиска2 = "Дата" И ОператорСравнения = "И", тогда таблица построителя должна иметь
// колонки "Номер", где лежит номер документа и "Дата", где лежит дата документа.
Если ОператорСравнения = "ИЛИ" Тогда
ИмяКолонкиСравнения = СтрокаТаблицы.ИмяКолонки;
Иначе
ИмяКолонкиСравнения = РеквизитСравнения;
КонецЕсли;
ВставкаУсловияСоединения = ВставкаУсловияСоединения
+ ?(ПустаяСтрока(ВставкаУсловияСоединения), "", Символы.ПС + "
| " + ОператорСравнения + " ") + ВходнаяТаблицаСтрока + ИмяКолонкиСравнения
+ " = " + ИмяОбъекта + Итерация + "." + РеквизитСравнения;
КонецЦикла;
Если Не ПустаяСтрока(ВставкаУсловияСоединения) Тогда
ВставкаИсточники = ВставкаИсточники + "
| ЛЕВОЕ СОЕДИНЕНИЕ " + СтрЗаменить(СтрокаТаблицы.ТипЗначения, СсылкаСтрока, "")
+ " КАК " + ИмяОбъекта + Итерация + "
| ПО ВходнаяТаблица." + СтрокаТаблицы.ИмяКолонки + " <> """" И "
+ ВходнаяТаблицаСтрока + СтрокаТаблицы.ИмяКолонки + " <> 0
| И (" + ВставкаУсловияСоединения + ")";
КонецЕсли;
ВставкаБазовые = ВставкаБазовые + ВходнаяТаблицаСтрока + СтрокаТаблицы.ИмяКолонки
+ " КАК " + СтрокаТаблицы.ИмяКолонки + "Служебный," + Символы.ПС;
КонецЕсли;
ИначеЕсли СтрНайти(СтрокаТаблицы.ТипЗначения, "Перечисление") <> 0 Тогда
КолонкаПеречисления = ТЗ.Колонки.Добавить(СтрокаТаблицы.ИмяКолонки + СтрокаНеОбрабатывать,
Новый ОписаниеТипов(СтрокаТаблицы.ТипЗначения));
СоответствиеПеречислений.Вставить(СтрокаТаблицы.ИмяКолонки, СтрокаТаблицы.ТипЗначения);
ВставкаВТ = СтрЗаменить(ВставкаВТ, "." + СтрокаТаблицы.ИмяКолонки + " КАК", "." + КолонкаПеречисления.Имя + " КАК");
ВставкаБазовые = ВставкаБазовые + СтрШаблон(ШаблонИмяКолонки, СтрокаТаблицы.ИмяКолонки);
ИначеЕсли Не СтрНайти(СтрокаТаблицы.ИмяКолонки, СтрокаНеОбрабатывать) > 0 Тогда
ВставкаБазовые = ВставкаБазовые + СтрШаблон(ШаблонИмяКолонки, СтрокаТаблицы.ИмяКолонки);
Если СтрНайти(СтрокаТаблицы.ТипЗначения, "Дата") <> 0
И ТЗ.Колонки.Найти(СтрокаТаблицы.ИмяКолонки + "Строкой") <> Неопределено Тогда
СтруктураИменКолонокДат.Вставить(СтрокаТаблицы.ИмяКолонки, "");
КонецЕсли;
КонецЕсли;
КонецЦикла;
ВставкаВТ = ВставкаВТ + "ВходнаяТаблица.ПорядковыйНомер Как ПорядковыйНомер";
КоличествоСимволовЛев = 2;
ВставкаБазовые = Лев(ВставкаБазовые, СтрДлина(ВставкаБазовые) - КоличествоСимволовЛев);
Если КонвертироватьДаты Тогда
ПрисвоитьНомераФорматовКолонокДат(ТЗ, СтруктураИменКолонокДат);
КонецЕсли;
Для Каждого СтрокаТаблицы Из ТЗ Цикл
Для Каждого ИмяМассива Из МассивИменСсылочных Цикл
СтрокаТаблицы[ИмяМассива + КодЧисломСтрока] = ОписаниеТипаЧисло15.ПривестиЗначение(СтрокаТаблицы[ИмяМассива]);
КонецЦикла;
Для Каждого Колонка Из СоответствиеПеречислений Цикл
ИмяПеречисления = СтрЗаменить(Колонка.Значение, "ПеречислениеСсылка.", "");
Для Каждого ТекЭлемент Из Метаданные.Перечисления[ИмяПеречисления].ЗначенияПеречисления Цикл
Если НРег(ТекЭлемент.Синоним) = НРег(СтрокаТаблицы[Колонка.Ключ]) Тогда
СтрокаТаблицы[Колонка.Ключ + СтрокаНеОбрабатывать] = Перечисления[ИмяПеречисления][ТекЭлемент.Имя];
Прервать;
КонецЕсли;
КонецЦикла;
КонецЦикла;
Если КонвертироватьДаты Тогда
Для Каждого КлючИЗначение Из СтруктураИменКолонокДат Цикл
СтрокаТаблицы[КлючИЗначение.Ключ] = ПреобразоватьДатуИзСтрокиПоФормату(
СтрокаТаблицы[КлючИЗначение.Ключ + "Строкой"], КлючИЗначение.Значение);
КонецЦикла;
КонецЕсли;
КонецЦикла;
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| #ВставкаВТ
|ПОМЕСТИТЬ ВходнаяТаблица
|ИЗ
| &ВходнаяТаблица КАК ВходнаяТаблица
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| #ВставкаСсылочные
| #ВставкаБазовые
|ИЗ
| ВходнаяТаблица КАК ВходнаяТаблица
| #ВставкаИсточники
|
|УПОРЯДОЧИТЬ ПО
| ВходнаяТаблица.ПорядковыйНомер";
Запрос.Текст = СтрЗаменить(Запрос.Текст, "#ВставкаВТ", ВставкаВТ);
Запрос.Текст = СтрЗаменить(Запрос.Текст, "#ВставкаСсылочные", ВставкаСсылочные);
Запрос.Текст = СтрЗаменить(Запрос.Текст, "#ВставкаБазовые", ВставкаБазовые);
Запрос.Текст = СтрЗаменить(Запрос.Текст, "#ВставкаИсточники", ВставкаИсточники);
Запрос.УстановитьПараметр("ВходнаяТаблица", ТЗ);
РезультатЗапроса = Запрос.Выполнить();
ВыгрузкаРезультатаЗапроса = РезультатЗапроса.Выгрузить();
Возврат ВыгрузкаРезультатаЗапроса;
КонецФункции
// Возвращает таблицу значений без null в ячейках
//
// Параметры:
// ТаблицаЗначений - ТаблицаЗначений - таблица, в которой необходимо подменить значения
// фИзменилиТаблицу - Булево - флаг, оповещающий о том, что в таблице были выполнены замены
//
Процедура ТаблицаЗначенийБезNull(ТаблицаЗначений, фИзменилиТаблицу = Ложь) Экспорт
фИзменилиТаблицу = Ложь;
чКрайний = ТаблицаЗначений.Колонки.Количество() - 1;
Для чИндекс = 0 По чКрайний Цикл
ТипКолонки = ТаблицаЗначений.Колонки[чИндекс].ТипЗначения;
Если ТипКолонки.СодержитТип(Тип("Null")) Тогда
ИмяКолонки = ТаблицаЗначений.Колонки[чИндекс].Имя;
ЗаголовокКолонки = ТаблицаЗначений.Колонки[чИндекс].Заголовок;
ШиринаКолонки = ТаблицаЗначений.Колонки[чИндекс].Ширина;
ЗначениеКолонки = ТаблицаЗначений.ВыгрузитьКолонку(чИндекс);
ТипКолонки = Новый ОписаниеТипов(ТипКолонки, ,"NULL",
ТипКолонки.КвалификаторыЧисла,
ТипКолонки.КвалификаторыСтроки,
ТипКолонки.КвалификаторыДаты,
ТипКолонки.КвалификаторыДвоичныхДанных);
ТаблицаЗначений.Колонки.Удалить(чИндекс);
ТаблицаЗначений.Колонки.Вставить(чИндекс, ИмяКолонки, ТипКолонки, ЗаголовокКолонки, ШиринаКолонки);
ТаблицаЗначений.ЗагрузитьКолонку(ЗначениеКолонки, чИндекс);
фИзменилиТаблицу = Истина;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
#КонецОбласти // ПрограммныйИнтерфейс
#Область СлужебныеПроцедурыИФункции
Функция ПолучитьПромежуточнуюТаблицуЗначенийИзТабличногоДокумента(
ТабДок, НомерСтроки, Макет, СопоставлениеПоНаименованию)
Если Не НомерСтроки = 1 Тогда
ТабДок.УдалитьОбласть(ТабДок.Область("R1:R" + Строка(НомерСтроки - 1)), ТипСмещенияТабличногоДокумента.ПоВертикали);
КонецЕсли;
Если Не СопоставлениеПоНаименованию Тогда
ПреобразоватьТабличныйДокументПоследовательнымСопоставлением(ТабДок, Макет);
Иначе
ПреобразоватьТабличныйДокументСопоставлениемПоНаименованиюКолонок(ТабДок, Макет);
КонецЕсли;
ПЗ = Новый ПостроительЗапроса;
ПЗ.ИсточникДанных = Новый ОписаниеИсточникаДанных(ТабДок.Область());
ПЗ.ДобавлениеПредставлений = ТипДобавленияПредставлений.Добавлять;
ПЗ.ЗаполнитьНастройки();
ПЗ.Выполнить();
ТЗ = ПЗ.Результат.Выгрузить();
Если СопоставлениеПоНаименованию Тогда
// Дополняем колонками из макета, если в ТД они отсутствовали
Для Каждого СтрокаМакета Из Макет Цикл
Если ТЗ.Колонки.Найти(СтрокаМакета.ИмяКолонки) = Неопределено Тогда
ТЗ.Колонки.Добавить(СтрокаМакета.ИмяКолонки, Новый ОписаниеТипов(СтрокаМакета.ТипЗначения));
Иначе
// Для колонок с типом Дата необходимо преобразование
Если СтрокаМакета.ТипЗначения = "Дата" Тогда
ТЗ.Колонки[СтрокаМакета.ИмяКолонки].Имя = ТЗ.Колонки[СтрокаМакета.ИмяКолонки].Имя + "Строкой";
ТЗ.Колонки.Добавить(СтрокаМакета.ИмяКолонки, Новый ОписаниеТипов("Дата"));
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЕсли;
// Удаляем пустые строки, которые остались от объединения строк
ИмяКолонки1 = ТЗ.Колонки[0].Имя;
ИмяКолонки2 = ТЗ.Колонки[1].Имя;
ИмяКолонки3 = ТЗ.Колонки[2].Имя;
КоличествоСтрок = ТЗ.Количество() - 1;
Пока КоличествоСтрок >= 0 Цикл
СтрокаТаблицы = ТЗ[КоличествоСтрок];
Если ПустаяСтрока(СтрокаТаблицы[ИмяКолонки1])
И ПустаяСтрока(СтрокаТаблицы[ИмяКолонки2])
И ПустаяСтрока(СтрокаТаблицы[ИмяКолонки3]) Тогда
ТЗ.Удалить(СтрокаТаблицы);
КонецЕсли;
КоличествоСтрок = КоличествоСтрок - 1;
КонецЦикла;
ТЗ.Колонки.Добавить("ПорядковыйНомер", Новый ОписаниеТипов("Число"));
Возврат ТЗ;
КонецФункции
Процедура ПреобразоватьТабличныйДокументПоследовательнымСопоставлением(ТабДок, Макет)
ТабДок.ВставитьОбласть(ТабДок.Область("R1"),
ТабДок.Область("R1"),
ТипСмещенияТабличногоДокумента.ПоГоризонтали);
Табдок.Область("R1").Очистить(Истина, Истина, Истина);
Счетчик = 0;
Для Каждого СтрокаТаблицы Из Макет Цикл
Счетчик = Счетчик + 1;
Если Не ЗначениеЗаполнено(СтрокаТаблицы.ТипЗначения) Тогда
Продолжить;
КонецЕсли;
ТабДок.Область("R1" + "C" + Строка(Счетчик)).Текст = СтрокаТаблицы.ИмяКолонки;
КонецЦикла;
КонецПроцедуры
Процедура ПреобразоватьТабличныйДокументСопоставлениемПоНаименованиюКолонок(ТабДок, Макет)
Счетчик = 1;
КолонкиКУдалению = Новый Массив;
ТекстШапки = СокрЛП(ТабДок.Область("R1" + "C" + Строка(Счетчик)).Текст);
Пока Не ПустаяСтрока(ТекстШапки) Цикл
ИмяКолонки = "";
// Сверяем наименование колонки ТД и наименование из макета
Для Каждого СтрокаТаблицы Из Макет Цикл
Если Не ЗначениеЗаполнено(СтрокаТаблицы.ТипЗначения) Тогда
Продолжить;
КонецЕсли;
Если ПроверитьСоответствиеИменКолонок(ТекстШапки, СтрокаТаблицы.ИмяВТабДоке, СтрокаТаблицы.ИмяКолонки) Тогда
ИмяКолонки = СтрокаТаблицы.ИмяКолонки;
Прервать;
КонецЕсли;
КонецЦикла;
// Подменяем имя для работы с построителем; если колонки нет, то готовим ее к удалению
Если Не ПустаяСтрока(ИмяКолонки) Тогда
ТабДок.Область("R1" + "C" + Строка(Счетчик)).Текст = ИмяКолонки;
Иначе
КолонкиКУдалению.Добавить(Счетчик);
КонецЕсли;
Счетчик = Счетчик + 1;
ТекстШапки = СокрЛП(ТабДок.Область("R1" + "C" + Строка(Счетчик)).Текст);
КонецЦикла;
// Удаляем ненужные колонки
КоличествоКолонокКУдалению = КолонкиКУдалению.Количество() - 1;
Пока КоличествоКолонокКУдалению >= 0 Цикл
НомерКолонки = КолонкиКУдалению[КоличествоКолонокКУдалению];
ТабДок.УдалитьОбласть(ТабДок.Область("C" + Строка(НомерКолонки)), ТипСмещенияТабличногоДокумента.ПоГоризонтали);
КоличествоКолонокКУдалению = КоличествоКолонокКУдалению - 1;
КонецЦикла;
КонецПроцедуры
Функция ПроверитьСоответствиеИменКолонок(ТекстШапки, ИмяВТабДоке, ИмяКолонки)
Возврат (ЗначениеЗаполнено(ИмяВТабДоке) И ТекстШапки = ИмяВТабДоке)
Или (Не ЗначениеЗаполнено(ИмяВТабДоке) И ТекстШапки = ИмяКолонки);
КонецФункции
Процедура ПрисвоитьНомераФорматовКолонокДат(ТЗ, СтруктураИменКолонокДат)
Если Не ТЗ.Количество() Тогда
Возврат;
КонецЕсли;
ПерваяСтрокаТаблицы = ТЗ[0];
Для Каждого КлючИЗначение Из СтруктураИменКолонокДат Цикл
ЗначениеКолонки = ПерваяСтрокаТаблицы[КлючИЗначение.Ключ + "Строкой"];
Если ПустаяСтрока(ЗначениеКолонки) Тогда
Продолжить;
КонецЕсли;
СтруктураИменКолонокДат.Вставить(КлючИЗначение.Ключ, ПолучитьНомерФорматаДатыИзСтроки(ЗначениеКолонки));
КонецЦикла;
КонецПроцедуры
// Получает номер формата даты из строки
//
// Параметры:
// ЗначениеКолонки - Строка - дата строкой
//
// Возвращаемое значение:
// Строка - номер формата с разделителями "_". Первый разряд показывает какой разделитель используется
// в представлении даты, второй разряд показывает положение дня, месяца и года по отношению друг к другу, третий разряд
// показывает представление времени в дате. Если номер формата "000" - преобразование происходит из функции XMLЗначение.
// Первый разряд принимает значения:
// - 1 - разделитель ".";
// - 2 - "/";
// - 3 - "-";
// - 4 - " ";
// Второй разряд принимает значения:
// - 1 - год идет первым, потом месяц и день;
// - 2 - сначала день, потом месяц и год;
// - 3 - сначала день, месяц СТРОКОЙ и год;
// Третий разряд принимает значения:
// - 0 - время отсутствует;
// - 1 - время стандартное, 24-часовое представление
// - 2 - время в 12-ти часовом представлении (AM / PM)
//
// Примеры номеров форматов:
// - 1_1_2 - "2021.12.01 8:10 PM";
// - 2_1_0 - "2021/12/01";
// - 1_3_1 - "01.дек.2021 20:10";
// - 3_1_1 - "2021-12-01 20:10"
//
Функция ПолучитьНомерФорматаДатыИзСтроки(ЗначениеКолонки)
ЕстьВремя = СтрНайти(ЗначениеКолонки, ":") > 0;
ЭтоУниверсальноеВремя = Ложь;
Если ЕстьВремя Тогда
МассивРазделителей = пбп_СтроковыеФункцииКлиентСервер.РазложитьСтрокуВМассивПодстрок(
ЗначениеКолонки, ":", Истина, Истина);
Если СтрНайти(МассивРазделителей[1], "AM") > 0
Или СтрНайти(МассивРазделителей[1], "PM") > 0 Тогда
РазрядВремени = "2";
Иначе
РазрядВремени = "1";
КонецЕсли;
МассивРазделителейДатаВремя = пбп_СтроковыеФункцииКлиентСервер.РазложитьСтрокуВМассивПодстрок(
МассивРазделителей[0], " ", Истина, Истина);
КоличествоРазделителей = 2;
Если МассивРазделителейДатаВремя.Количество() = КоличествоРазделителей Тогда
ТолькоДата = МассивРазделителейДатаВремя[0];
ИначеЕсли МассивРазделителейДатаВремя.Количество() = 0 Тогда
МассивРазделителейДатаВремя = пбп_СтроковыеФункцииКлиентСервер.РазложитьСтрокуВМассивПодстрок(
МассивРазделителей[0], "T", Истина, Истина);
Если МассивРазделителейДатаВремя.Количество() = КоличествоРазделителей Тогда
ТолькоДата = МассивРазделителейДатаВремя[0];
ЭтоУниверсальноеВремя = Истина;
КонецЕсли;
Иначе
ТолькоДата = ПолучитьТолькоДатуЕслиРазделительПробел(МассивРазделителейДатаВремя);
КонецЕсли;
Иначе
ТолькоДата = ЗначениеКолонки;
РазрядВремени = "0";
КонецЕсли;
Если Не ЭтоУниверсальноеВремя Тогда
Если СтрНайти(ТолькоДата, ".") > 0 Тогда
РазрядРазделителя = "1";
РазрядФормата = ПолучитьРазрядФорматаДатыИзСтроки(ЗначениеКолонки, ".");
ИначеЕсли СтрНайти(ТолькоДата, "/") > 0 Тогда
РазрядРазделителя = "2";
РазрядФормата = ПолучитьРазрядФорматаДатыИзСтроки(ЗначениеКолонки, "/");
ИначеЕсли СтрНайти(ТолькоДата, "-") > 0 Тогда
РазрядРазделителя = "3";
РазрядФормата = ПолучитьРазрядФорматаДатыИзСтроки(ЗначениеКолонки, "-");
Иначе
РазрядРазделителя = "4";
РазрядФормата = ПолучитьРазрядФорматаДатыИзСтроки(ЗначениеКолонки, " ");
КонецЕсли;
Иначе
РазрядРазделителя = "0";
РазрядФормата = "0";
РазрядВремени = "0";
КонецЕсли;
Возврат РазрядРазделителя + "_" + РазрядФормата + "_" + РазрядВремени;
КонецФункции
Функция ПолучитьРазрядФорматаДатыИзСтроки(ЗначениеКолонки, Разделитель)
МассивРазделителей = пбп_СтроковыеФункцииКлиентСервер.РазложитьСтрокуВМассивПодстрок(
ЗначениеКолонки, Разделитель, Истина, Истина);
КоличествоПервыхСимволов = 3;
МаксКоличествоДнейВМесяце = 31;
СокрМесяц = ТРег(Лев(МассивРазделителей[1], КоличествоПервыхСимволов));
Если Число(МассивРазделителей[0]) > МаксКоличествоДнейВМесяце Тогда // тут год
РазрядФормата = "1";
ИначеЕсли пбп_ОбщегоНазначенияКлиентСервер.ПолучитьНомерМесяцаПоСтроковомуПредставлению(СокрМесяц) = 0 Тогда
РазрядФормата = "2";
Иначе
РазрядФормата = "3";
КонецЕсли;
Возврат РазрядФормата;
КонецФункции
Функция ПолучитьТолькоДатуЕслиРазделительПробел(МассивРазделителейДатаВремя)
КоличествоСмещений = 2;
КоличествоРазделителей = МассивРазделителейДатаВремя.Количество() - КоличествоСмещений; // В последнем часы
Для Разделитель = 0 По КоличествоРазделителей Цикл
ТолькоДата = ТолькоДата + ?(ПустаяСтрока(ТолькоДата), "", " ") + МассивРазделителейДатаВремя[Разделитель];
КонецЦикла;
Возврат ТолькоДата;
КонецФункции
// Преобразовать дату из строки по строковому формату
//
// Параметры:
// ВхЗначение - Строка - дата строкой
// НомерФормата - Строка - номер формата с разделителями "_". Подробнее см. в ПолучитьНомерФорматаДатыИзСтроки
//
// Возвращаемое значение:
// Дата - дата, полученная из преобразования даты строкой по формату
//
Функция ПреобразоватьДатуИзСтрокиПоФормату(ВхЗначение, НомерФормата)
ПреобразованнаяДата = Неопределено;
Если НомерФормата = "000" Тогда
ПреобразованнаяДата = XMLЗначение(Тип("Дата"), ВхЗначение);
Иначе
РазрядыФормата = пбп_СтроковыеФункцииКлиентСервер.РазложитьСтрокуВМассивПодстрок(НомерФормата, "_");
СтрокаВремя = "";
Если РазрядыФормата[2] = "0" Тогда
СтрокаВремя = "00:00:00";
ТолькоДата = ВхЗначение;
Иначе
МассивРазделителей = пбп_СтроковыеФункцииКлиентСервер.РазложитьСтрокуВМассивПодстрок(
ВхЗначение, ":", Истина, Истина);
МассивРазделителейДатаВремя = пбп_СтроковыеФункцииКлиентСервер.РазложитьСтрокуВМассивПодстрок(
МассивРазделителей[0], " ", Истина, Истина);
Если РазрядыФормата[0] = "4" Тогда
ТолькоДата = ПолучитьТолькоДатуЕслиРазделительПробел(МассивРазделителейДатаВремя);
Иначе
ТолькоДата = МассивРазделителейДатаВремя[0];
КонецЕсли;
Если РазрядыФормата[1] = "1" Тогда
Часы = МассивРазделителейДатаВремя[МассивРазделителейДатаВремя.Количество() - 1];
МинутыСекунды = МассивРазделителей[1];
Иначе
ЧасыБезСдвигаЧисло = Число(МассивРазделителейДатаВремя[МассивРазделителейДатаВремя.Количество() - 1]);
КоличествоСимволовДоПослеОбеда = 2;
КоличествоЧасовСдвига = 12;
Если Прав(МинутыСекунды, КоличествоСимволовДоПослеОбеда) = "PM" Тогда
Часы = ЧасыБезСдвигаЧисло + КоличествоЧасовСдвига;
Иначе
Часы = ЧасыБезСдвигаЧисло;
КонецЕсли;
МинутыСекунды = СтрЗаменить(МинутыСекунды, " AM", "");
МинутыСекунды = СтрЗаменить(МинутыСекунды, " PM", "");
КонецЕсли;
СтрокаВремя = Строка(Часы) + ":" + МинутыСекунды;
КонецЕсли;
Если РазрядыФормата[0] = "1" Тогда
РазделительРазрядов = ".";
ИначеЕсли РазрядыФормата[0] = "2" Тогда
РазделительРазрядов = "/";
ИначеЕсли РазрядыФормата[0] = "3" Тогда
РазделительРазрядов = "-";
Иначе
РазделительРазрядов = " ";
КонецЕсли;
МассивГодМесяцДата = пбп_СтроковыеФункцииКлиентСервер.РазложитьСтрокуВМассивПодстрок(
ТолькоДата, РазделительРазрядов, Истина, Истина);
Если РазрядыФормата[1] = "1" Тогда
Год = МассивГодМесяцДата[0];
Месяц = МассивГодМесяцДата[1];
День = МассивГодМесяцДата[2];
ИначеЕсли РазрядыФормата[1] = "2" Тогда
Год = МассивГодМесяцДата[2];
Месяц = МассивГодМесяцДата[1];
День = МассивГодМесяцДата[0];
Иначе
Год = МассивГодМесяцДата[2];
КоличествоПервыхСимволов = 3;
СокрМесяц = ТРег(Лев(МассивГодМесяцДата[1], КоличествоПервыхСимволов));
Месяц = пбп_ОбщегоНазначенияКлиентСервер.ПолучитьНомерМесяцаПоСтроковомуПредставлению(СокрМесяц);
День = МассивГодМесяцДата[0];
КонецЕсли;
НомерЧислаБезНуля = 10;
Если Число(Месяц) < НомерЧислаБезНуля И Лев(Месяц, 1) <> "0" Тогда
Месяц = "0" + Месяц;
КонецЕсли;
Если Число(День) < НомерЧислаБезНуля И Лев(День, 1) <> "0" Тогда
День = "0" + День;
КонецЕсли;
СтрокаДата = День + "." + Месяц + "." + Год;
ПреобразованнаяДата = Дата(СтрокаДата + " " + СтрокаВремя);
КонецЕсли;
Возврат ПреобразованнаяДата;
КонецФункции
#КонецОбласти // СлужебныеПроцедурыИФункции

View File

@ -1076,7 +1076,7 @@
Функция ПолучитьДатуИзТестовогоФорматаBASHLinux(СтрокаСвойств)
ГодЧислом = ?(СтрокаСвойств.ЭтоВремя, Год(ТекущаяДатаСеанса()), Число(СтрокаСвойств.ГодВремя));
Месяц = ПолучитьНомерМесяцаПоСтроковомуПредставлению(СтрокаСвойств.Месяц);
Месяц = пбп_ОбщегоНазначенияКлиентСервер.ПолучитьНомерМесяцаПоСтроковомуПредставлению(СтрокаСвойств.Месяц);
ЧислоМесяца = СтрокаСвойств.Число;
ЧасВремя = ?(СтрокаСвойств.ЭтоВремя, СтрокаСвойств.ГодВремя, "00:00");
@ -1089,52 +1089,6 @@
КонецФункции
Функция ПолучитьНомерМесяцаПоСтроковомуПредставлению(МесяцСтрокойСокр)
МесяцВРег = ВРег(МесяцСтрокойСокр);
// BSLLS:Typo-off
Если МесяцВРег = "ЯНВ"
Или МесяцВРег = "JAN" Тогда
МесяцЧислом = 1;
ИначеЕсли МесяцВРег = "ФЕВ"
Или МесяцВРег = "FEB" Тогда
МесяцЧислом = 2;
ИначеЕсли МесяцВРег = "МАР"
Или МесяцВРег = "MAR" Тогда
МесяцЧислом = 3;
ИначеЕсли МесяцВРег = "АПР"
Или МесяцВРег = "APR" Тогда
МесяцЧислом = 4;
ИначеЕсли МесяцВРег = "МАЙ"
Или МесяцВРег = "MAY" Тогда
МесяцЧислом = 5;
ИначеЕсли МесяцВРег = "ИЮН"
Или МесяцВРег = "JUN" Тогда
МесяцЧислом = 6;
ИначеЕсли МесяцВРег = "ИЮЛ"
Или МесяцВРег = "JUL" Тогда
МесяцЧислом = 7;
ИначеЕсли МесяцВРег = "АВГ"
Или МесяцВРег = "AUG" Тогда
МесяцЧислом = 8;
ИначеЕсли МесяцВРег = "СЕН"
Или МесяцВРег = "SEP" Тогда
МесяцЧислом = 9;
ИначеЕсли МесяцВРег = "ОКТ"
Или МесяцВРег = "OCT" Тогда
МесяцЧислом = 10;
ИначеЕсли МесяцВРег = "НОЯ"
Или МесяцВРег = "NOV" Тогда
МесяцЧислом = 11;
Иначе // Декабрь
МесяцЧислом = 12;
КонецЕсли;
// BSLLS:Typo-on
Возврат МесяцЧислом;
КонецФункции
#Область SFTPWindows
Функция ПроверитьСуществованиеУтилитыПодключенияКSFTPWindows()

View File

@ -144,14 +144,174 @@
ВнешниеИсточникиДанных[ИмяВнешнегоИсточникаДанных].УстановитьОбщиеПараметрыСоединения(ПараметрыСоединения);
ПользовательСсылка = пбп_ПользователиСлужебный.ТекущийПользователь();
ТекущийПользователь = пбп_ПользователиСлужебный.НайтиПоСсылке(ПользовательСсылка);
ВнешниеИсточникиДанных[ИмяВнешнегоИсточникаДанных].УстановитьПараметрыСоединенияПользователя(
пбп_Пользователи.ТекущийПользователь(), ПараметрыСоединения);
ТекущийПользователь.Имя, ПараметрыСоединения);
ВнешниеИсточникиДанных[ИмяВнешнегоИсточникаДанных].УстановитьПараметрыСоединенияСеанса(ПараметрыСоединения);
ВнешниеИсточникиДанных[ИмяВнешнегоИсточникаДанных].УстановитьСоединение();
КонецПроцедуры
// Получает таблицу данных из внешнего источника посредством выполнения запроса по условиям
//
// Параметры:
// ИнтеграционныйПоток - СправочникСсылка.пбп_ИнтеграционныеПотоки - ссылка на интеграционный поток
// ПоляЗапроса - Строка - название полей таблицы, перечисленных через запятую
// ПараметрыЗапроса - Структура - ключом является наименование поля запроса, по которому необходимо
// установить условие, значением - значение параметра запроса
// КоличествоПервых - Число - количество первых строк выборки. Если не заполнено, то условия по ПЕРВЫЕ нет
// СтруктураИстории - Структура - см. ПолучитьСтруктуруЗаписиИстории
//
// Возвращаемое значение:
// Строка, ТаблицаЗначений - таблица значений с данными, полученными из внешнего источника,
// с типизированными колонками или строка с ошибкой
//
Функция ПолучитьТаблицуДанныхИзВнешнегоИсточникаПоУсловиям(ИнтеграционныйПоток,
ПоляЗапроса = "", ПараметрыЗапроса = Неопределено, КоличествоПервых = 0, СтруктураИстории = Неопределено) Экспорт
ЗаголовокОшибки = "Данные не были получены из внешнего источника данных";
СообщениеОбОшибке = "";
РеквизитыОбъекта = пбп_ОбщегоНазначенияСервер.ЗначенияРеквизитовОбъекта(
ИнтеграционныйПоток, "НастройкаИнтеграции.ИмяОбъекта, ТочкаВхода");
Если Не ЗначениеЗаполнено(РеквизитыОбъекта.НастройкаИнтеграцииИмяОбъекта) Тогда
ПолноеОписаниеОшибки = СтрШаблон("ru = '%1. Подробно: %2';", ЗаголовокОшибки,
"в настройках интеграции не заполнено наименование внешнего источника данных");
СообщениеОбОшибке = НСтр(ПолноеОписаниеОшибки);
КонецЕсли;
Если Не ЗначениеЗаполнено(РеквизитыОбъекта.ТочкаВхода) Тогда
ПолноеОписаниеОшибки = СтрШаблон("ru = '%1. Подробно: %2';", ЗаголовокОшибки,
"в интеграционном потоке не заполнено имя таблицы внешнего источника данных");
СообщениеОбОшибке = НСтр(ПолноеОписаниеОшибки);
КонецЕсли;
Если Не ПустаяСтрока(СообщениеОбОшибке) Тогда
Возврат СообщениеОбОшибке;
КонецЕсли;
Попытка
ТаблицаВыборки = ИнициализироватьТаблицуЗначенийИзТаблицыВнешнегоИсточника(
РеквизитыОбъекта.НастройкаИнтеграцииИмяОбъекта, РеквизитыОбъекта.ТочкаВхода, ПоляЗапроса);
Запрос = Новый Запрос;
ТекстЗапроса = "ВЫБРАТЬ
| &ПоляЗапроса
|ИЗ
| ВнешнийИсточникДанных." + РеквизитыОбъекта.НастройкаИнтеграцииИмяОбъекта
+ ".Таблица." + РеквизитыОбъекта.ТочкаВхода + " КАК Таблица";
Если КоличествоПервых <> 0 Тогда
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "ВЫБРАТЬ", "ВЫБРАТЬ ПЕРВЫЕ " + КоличествоПервых);
КонецЕсли;
Если Не ПустаяСтрока(ПоляЗапроса) Тогда
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&ПоляЗапроса", ПоляЗапроса);
Иначе
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&ПоляЗапроса", "Таблица.*");
КонецЕсли;
УсловияЗапроса = "";
// Установка предопределенных параметров запроса из интеграционного потока
Для Каждого СтрокаПредопределенногоПараметра Из ИнтеграционныйПоток.ПараметрыВхода Цикл
НуженПеренос = ?(ПустаяСтрока(УсловияЗапроса), "", "
| И ");
УсловияЗапроса = УсловияЗапроса + СтрШаблон("%1Таблица.%2 = &%2",
НуженПеренос, СтрокаПредопределенногоПараметра.Имя);
Запрос.УстановитьПараметр(
СтрокаПредопределенногоПараметра.Имя,
СтрокаПредопределенногоПараметра.ЗначениеПоУмолчанию);
КонецЦикла;
// Установка опциональных параметров запроса
Для Каждого КлючИЗначение Из ПараметрыЗапроса Цикл
НуженПеренос = ?(ПустаяСтрока(УсловияЗапроса), "", "
| И ");
УсловияЗапроса = УсловияЗапроса + СтрШаблон("%1Таблица.%2 = &%2",
НуженПеренос, КлючИЗначение.Ключ);
Запрос.УстановитьПараметр(КлючИЗначение.Ключ, КлючИЗначение.Значение);
КонецЦикла;
Если Не ПустаяСтрока(УсловияЗапроса) Тогда
ТекстЗапроса = ТекстЗапроса + "
|ГДЕ
| " + УсловияЗапроса;
КонецЕсли;
Запрос.Текст = ТекстЗапроса;
Если СтруктураИстории <> Неопределено Тогда
СтруктураИстории.ИсходящееСообщение = пбп_ИнтеграцииСлужебный
.ПолучитьПредставлениеТекстЗапросаВнешнегоИсточникаДанных(Запрос);
НачалоВызова = ТекущаяДатаСеанса();
КонецЕсли;
РезультатЗапроса = Запрос.Выполнить();
Если СтруктураИстории <> Неопределено Тогда
СтруктураИстории.ДлительностьВызова = ТекущаяДатаСеанса() - НачалоВызова;
КонецЕсли;
ВыборкаРезультатаЗапроса = РезультатЗапроса.Выбрать();
Пока ВыборкаРезультатаЗапроса.Следующий() Цикл
ЗаполнитьЗначенияСвойств(ТаблицаВыборки.Добавить(), ВыборкаРезультатаЗапроса);
КонецЦикла;
Возврат ТаблицаВыборки;
Исключение
СообщениеОбОшибке = ПолучитьПодробноеПредставлениеОшибкиИсключения(ЗаголовокОшибки, ИнформацияОбОшибке());
КонецПопытки;
Возврат СообщениеОбОшибке;
КонецФункции
// Возвращает инициализированную таблицу значений из таблицы внешнего
// источника по метаданным с типизированными колонками
//
// Параметры:
// ИмяВнешнегоИсточника - Строка - имя внешнего источника данных
// ИмяТаблицы - Строка - имя таблицы внешнего источника данных
// НеобходимыеПоля - Строка - название полей таблицы, перечисленных через запятую
//
// Возвращаемое значение:
// ТаблицаЗначений - пустая таблица значений с типизированными колонками
//
Функция ИнициализироватьТаблицуЗначенийИзТаблицыВнешнегоИсточника(
ИмяВнешнегоИсточника, ИмяТаблицы, НеобходимыеПоля = "") Экспорт
ТаблицаДанных = Новый ТаблицаЗначений;
МетаданныеИсточника = Метаданные.ВнешниеИсточникиДанных[ИмяВнешнегоИсточника];
МетаданныеТаблицы = МетаданныеИсточника.Таблицы[ИмяТаблицы];
МассивНужныхПолей = Новый Массив;
Если Не ПустаяСтрока(НеобходимыеПоля) Тогда
МассивНужныхПолей = пбп_СтроковыеФункцииКлиентСервер.РазложитьСтрокуВМассивПодстрок(
НеобходимыеПоля, ",", Истина, Истина);
КонецЕсли;
КоличествоНужныхПолей = МассивНужныхПолей.Количество();
Для Каждого ПолеТаблицы Из МетаданныеТаблицы.Поля Цикл
Если КоличествоНужныхПолей <> 0 И МассивНужныхПолей.Найти(ПолеТаблицы.Имя) = Неопределено Тогда
Продолжить;
КонецЕсли;
ТаблицаДанных.Колонки.Добавить(ПолеТаблицы.Имя, ПолеТаблицы.Тип);
КонецЦикла;
Возврат ТаблицаДанных;
КонецФункции
#КонецОбласти // ПрямоеПодключениеКБД
#Область REST

View File

@ -53,10 +53,9 @@
// Процедура создает запись справочника История интеграции с информацией о событии интеграции
//
// Параметры:
// СтруктураЗаписиИстории - Структура - описание действия (см. ПолучитьСтруктуруЗаписиИстории)
// ЭтоЗагрузка - Булево - Истина если это Загрузка, Ложь если это Выгрузка
// СтруктураЗаписиИстории - Структура - описание действия (см. ПолучитьСтруктуруЗаписиИстории)
//
Процедура СоздатьСообщениеИсторииИнтеграции(СтруктураЗаписиИстории, ЭтоЗагрузка) Экспорт
Процедура СоздатьСообщениеИсторииИнтеграции(СтруктураЗаписиИстории) Экспорт
УстановитьПривилегированныйРежим(Истина);
@ -70,18 +69,26 @@
НовоеСообщение.Пользователь = пбп_ПользователиСлужебный.ТекущийПользователь();
НовоеСообщение.ДлительностьОбмена = НовоеСообщение.ДатаИнтеграции - СтруктураЗаписиИстории.ДатаНачалаИнтеграции;
НовоеСообщение.ДлительностьВызова = СтруктураЗаписиИстории.ДлительностьВызова;
Если ЭтоЗагрузка Тогда
НаправлениеПотока = СтруктураЗаписиИстории.ИнтеграционныйПоток.НаправлениеПотока;
Если НаправлениеПотока = Перечисления.пбп_НаправленияИнтеграционныхПотоков.Входящий Тогда
Если НовоеСообщение.Ошибка Тогда
НовоеСообщение.Статус = Перечисления.пбп_СтатусыИнтеграции.ОшибкаЗагрузки;
Иначе
НовоеСообщение.Статус = Перечисления.пбп_СтатусыИнтеграции.Загружено;
КонецЕсли;
Иначе
ИначеЕсли НаправлениеПотока = Перечисления.пбп_НаправленияИнтеграционныхПотоков.Исходящий Тогда
Если НовоеСообщение.Ошибка Тогда
НовоеСообщение.Статус = Перечисления.пбп_СтатусыИнтеграции.ОшибкаВыгрузки;
Иначе
НовоеСообщение.Статус = Перечисления.пбп_СтатусыИнтеграции.Выгружено;
КонецЕсли;
Иначе
Если НовоеСообщение.Ошибка Тогда
НовоеСообщение.Статус = Перечисления.пбп_СтатусыИнтеграции.ОшибкаСлужебного;
Иначе
НовоеСообщение.Статус = Перечисления.пбп_СтатусыИнтеграции.Служебный;
КонецЕсли;
КонецЕсли;
ЗаполнитьЗначенияСвойств(НовоеСообщение, СтруктураЗаписиИстории);
Для Каждого Строка Из СтруктураЗаписиИстории.ОбъектыИнтеграции Цикл
@ -111,6 +118,38 @@
КонецПроцедуры
// Получает представление текста запроса внешнего источника данных
//
// Параметры:
// Запрос - Строка - текст запроса к таблице внешнего источника данных с добавлением значений параметров в текст
//
// Возвращаемое значение:
// Строка - текст запроса с заполненными значениями параметров
//
Функция ПолучитьПредставлениеТекстЗапросаВнешнегоИсточникаДанных(Запрос) Экспорт
ПредставлениеТекстаЗапроса = Запрос.Текст;
Для Каждого ПараметрЗапроса Из Запрос.Параметры Цикл
ТипЗначения = ТипЗнч(ПараметрЗапроса.Значение);
Если ТипЗначения = Тип("Строка") Тогда
ПредставлениеЗначения = """" + ПараметрЗапроса.Значение + """";
ИначеЕсли ТипЗначения = Тип("Дата") Тогда
ПредставлениеЗначения = "'" + Формат(ПараметрЗапроса.Значение, "ДЛФ=DT") + "'";
ИначеЕсли ТипЗначения = Тип("Булево") Тогда
ПредставлениеЗначения = Формат(ПараметрЗапроса.Значение, "БЛ=ЛОЖЬ; БИ=ИСТИНА");
Иначе
ПредставлениеЗначения = Формат(ПараметрЗапроса.Значение, "ЧГ=");
КонецЕсли;
ПредставлениеТекстаЗапроса = СтрЗаменить(ПредставлениеТекстаЗапроса,
"&" + ПараметрЗапроса.Ключ, ПредставлениеЗначения);
КонецЦикла;
Возврат ПредставлениеТекстаЗапроса;
КонецФункции
#КонецОбласти // ИсторияИнтеграции
#Область РаботаСДанными

View File

@ -74,7 +74,7 @@
Процедура ПриДобавленииПодсистемы(Описание) Экспорт
Описание.Имя = "ПроектнаяБиблиотекаПодсистем";
Описание.Версия = "1.0.3.10";
Описание.Версия = "1.0.3.11";
// Требуется библиотека стандартных подсистем.
Описание.ТребуемыеПодсистемы.Добавить("СтандартныеПодсистемы");

View File

@ -84,6 +84,60 @@
КонецФункции
// Получает номер месяца числом по строковому представлению
//
// Параметры:
// МесяцСтрокойСокр - Строка - первые 3 буквы названия месяца
//
// Возвращаемое значение:
// Число - номер месяца числом
//
Функция ПолучитьНомерМесяцаПоСтроковомуПредставлению(МесяцСтрокойСокр) Экспорт
Если МесяцСтрокойСокр = "Янв"
Или МесяцСтрокойСокр = "Jan" Тогда
МесяцЧислом = 1;
ИначеЕсли МесяцСтрокойСокр = "Фев"
Или МесяцСтрокойСокр = "Feb" Тогда
МесяцЧислом = 2;
ИначеЕсли МесяцСтрокойСокр = "Мар"
Или МесяцСтрокойСокр = "Mar" Тогда
МесяцЧислом = 3;
ИначеЕсли МесяцСтрокойСокр = "Апр"
Или МесяцСтрокойСокр = "Apr" Тогда
МесяцЧислом = 4;
ИначеЕсли МесяцСтрокойСокр = "Май"
Или МесяцСтрокойСокр = "May" Тогда
МесяцЧислом = 5;
ИначеЕсли МесяцСтрокойСокр = "Июн"
Или МесяцСтрокойСокр = "Jun" Тогда
МесяцЧислом = 6;
ИначеЕсли МесяцСтрокойСокр = "Июл"
Или МесяцСтрокойСокр = "Jul" Тогда
МесяцЧислом = 7;
ИначеЕсли МесяцСтрокойСокр = "Авг"
Или МесяцСтрокойСокр = "Aug" Тогда
МесяцЧислом = 8;
ИначеЕсли МесяцСтрокойСокр = "Сен"
Или МесяцСтрокойСокр = "Sep" Тогда
МесяцЧислом = 9;
ИначеЕсли МесяцСтрокойСокр = "Окт"
Или МесяцСтрокойСокр = "Oct" Тогда
МесяцЧислом = 10;
ИначеЕсли МесяцСтрокойСокр = "Ноя"
Или МесяцСтрокойСокр = "Nov" Тогда
МесяцЧислом = 11;
ИначеЕсли МесяцСтрокойСокр = "Dec"
Или МесяцСтрокойСокр = "Дек" Тогда
МесяцЧислом = 12;
Иначе
МесяцЧислом = 0;
КонецЕсли;
Возврат МесяцЧислом;
КонецФункции
#Область МетодыАналогиБСП
// Аналог метода БСП. Устанавливает свойство ИмяСвойства элемента формы с именем ИмяЭлемента в значение Значение.

View File

@ -36,6 +36,24 @@
КонецФункции
// Аналог метода БСП. Возвращает пользователя ИБ по ссылке справочника Пользователи или ВнешниеПользователи.
// Для поиска требуются административные права. Если административных прав нет,
// допустимо искать только пользователя для текущего пользователя ИБ.
//
// Параметры:
// Пользователь - СправочникСсылка.Пользователи
// - СправочникСсылка.ВнешниеПользователи
//
// Возвращаемое значение:
// ПользовательИнформационнойБазы - если найден.
// Неопределено - если пользователь ИБ не существует.
//
Функция НайтиПоСсылке(Пользователь) Экспорт
Возврат Неопределено;
КонецФункции
#КонецОбласти
#КонецОбласти

View File

@ -30,6 +30,14 @@
КонецФункции
// См. пбп_Пользователи.НайтиПоСсылке.
Функция НайтиПоСсылке(Пользователь) Экспорт
Модуль = ПолучитьМодуль();
Возврат Модуль.НайтиПоСсылке(Пользователь);
КонецФункции
#КонецОбласти
#КонецОбласти

View File

@ -122,7 +122,7 @@
КонецПроцедуры
// Заполняет таблицу предопределенных элементов справочника СправочникСсылка.пбп_МетодыИнтеграции.
// Заполняет таблицу предопределенных элементов справочника СправочникСсылка.пбп_ИнтеграционныеПотоки.
//
// Параметры:
// Таблица - ТаблицаЗначений - Таблица предопределенных элементов.
@ -133,6 +133,7 @@
НовыйМетод = Таблица.Добавить();
НовыйМетод.Наименование = "Интеграционный поток системы N";
НовыйМетод.ИдентификаторНастройки = "ИнтеграционныйПотокСистемыN";
НовыйМетод.НаправлениеПотока = Перечисления.пбп_НаправленияИнтеграционныхПотоков.Исходящий;
// КонецДобавления
КонецПроцедуры
@ -270,7 +271,8 @@
Колонки = Новый Структура;
// Добавление
Колонки.Вставить("НаправлениеПотока" , Новый ОписаниеТипов(
"ПеречислениеСсылка.пбп_НаправленияИнтеграционныхПотоков"));
// КонецДобавления
Возврат Колонки;

View File

@ -57,7 +57,7 @@
<xr:Item xsi:type="xr:MDObjectRef">Role.ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок</xr:Item>
</DefaultRoles>
<Vendor>Первый БИТ</Vendor>
<Version>1.0.3.10</Version>
<Version>1.0.3.11</Version>
<UpdateCatalogAddress/>
<IncludeHelpInContents>false</IncludeHelpInContents>
<UseManagedFormInOrdinaryApplication>false</UseManagedFormInOrdinaryApplication>
@ -280,9 +280,10 @@
<CommonModule>пбп_ЖурналРегистрацииСлужебный</CommonModule>
<CommonModule>пбп_ЗагрузкаФайлаЧерезТабличныйДокументВызовСервера</CommonModule>
<CommonModule>пбп_ЗагрузкаФайлаЧерезТабличныйДокументКлиент</CommonModule>
<CommonModule>пбп_ЗагрузкаФайлаЧерезТабличныйДокументСервер</CommonModule>
<CommonModule>пбп_ИнтеграцииFTPSFTP</CommonModule>
<CommonModule>пбп_ИнтеграцииСервер</CommonModule>
<CommonModule>пбп_ИнтеграцииСлужебный</CommonModule>
<CommonModule>пбп_ИнтеграцииFTPSFTP</CommonModule>
<CommonModule>пбп_КоннекторHTTP</CommonModule>
<CommonModule>пбп_МетодыРегламентныхЗаданийСервер</CommonModule>
<CommonModule>пбп_МодификацияКонфигурацииКлиентПереопределяемый</CommonModule>
@ -327,9 +328,9 @@
<CommonModule>пбп_СтроковыеФункцииСлужебныйКлиентСервер</CommonModule>
<CommonModule>пбп_СхемыЗапросов</CommonModule>
<CommonModule>пбп_ФайловаяСистема</CommonModule>
<CommonModule>пбп_ФайловаяСистемаПереадресация</CommonModule>
<CommonModule>пбп_ФайловаяСистемаКлиентПереадресация</CommonModule>
<CommonModule>пбп_ФайловаяСистемаКлиент</CommonModule>
<CommonModule>пбп_ФайловаяСистемаКлиентПереадресация</CommonModule>
<CommonModule>пбп_ФайловаяСистемаПереадресация</CommonModule>
<CommonModule>пбп_ФайловаяСистемаСлужебныйКлиент</CommonModule>
<EventSubscription>пбп_ДокументыОбработкаЗаполнения</EventSubscription>
<EventSubscription>пбп_ДокументыОбработкаПроведения</EventSubscription>
@ -368,6 +369,7 @@
<Enum>пбп_ТипыJSON</Enum>
<Enum>пбп_ТипыАвторизации</Enum>
<Enum>пбп_ФорматыИнтеграций</Enum>
<Enum>пбп_НаправленияИнтеграционныхПотоков</Enum>
<InformationRegister>пбп_СоответствияОбъектовИБ</InformationRegister>
<InformationRegister>пбп_СостоянияПредопределенныхЭлементов</InformationRegister>
<ChartOfCharacteristicTypes>пбп_ПредопределенныеЗначения</ChartOfCharacteristicTypes>

View File

@ -0,0 +1,79 @@
<?xml version="1.0" encoding="UTF-8"?>
<MetaDataObject xmlns="http://v8.1c.ru/8.3/MDClasses" xmlns:app="http://v8.1c.ru/8.2/managed-application/core" xmlns:cfg="http://v8.1c.ru/8.1/data/enterprise/current-config" xmlns:cmi="http://v8.1c.ru/8.2/managed-application/cmi" xmlns:ent="http://v8.1c.ru/8.1/data/enterprise" xmlns:lf="http://v8.1c.ru/8.2/managed-application/logform" xmlns:style="http://v8.1c.ru/8.1/data/ui/style" xmlns:sys="http://v8.1c.ru/8.1/data/ui/fonts/system" xmlns:v8="http://v8.1c.ru/8.1/data/core" xmlns:v8ui="http://v8.1c.ru/8.1/data/ui" xmlns:web="http://v8.1c.ru/8.1/data/ui/colors/web" xmlns:win="http://v8.1c.ru/8.1/data/ui/colors/windows" xmlns:xen="http://v8.1c.ru/8.3/xcf/enums" xmlns:xpr="http://v8.1c.ru/8.3/xcf/predef" xmlns:xr="http://v8.1c.ru/8.3/xcf/readable" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.16">
<Enum uuid="14d35922-293f-4d40-96fb-1188632f6a11">
<InternalInfo>
<xr:GeneratedType name="EnumRef.пбп_НаправленияИнтеграционныхПотоков" category="Ref">
<xr:TypeId>c8991acd-32d1-4ff9-a7de-6d0fd212d9f1</xr:TypeId>
<xr:ValueId>4283575a-860b-46b9-a52a-be0e167b1547</xr:ValueId>
</xr:GeneratedType>
<xr:GeneratedType name="EnumManager.пбп_НаправленияИнтеграционныхПотоков" category="Manager">
<xr:TypeId>76481515-b516-4445-ae1b-0a9687733056</xr:TypeId>
<xr:ValueId>ae119484-847e-4a56-ad0e-dc7090c447dd</xr:ValueId>
</xr:GeneratedType>
<xr:GeneratedType name="EnumList.пбп_НаправленияИнтеграционныхПотоков" category="List">
<xr:TypeId>675d3fb1-22e3-44c6-a37c-e0c24a5c248f</xr:TypeId>
<xr:ValueId>2e7de2a4-edd9-4696-8b05-0708903639cb</xr:ValueId>
</xr:GeneratedType>
</InternalInfo>
<Properties>
<Name>пбп_НаправленияИнтеграционныхПотоков</Name>
<Synonym>
<v8:item>
<v8:lang>ru</v8:lang>
<v8:content>Направления интеграционных потоков</v8:content>
</v8:item>
</Synonym>
<Comment/>
<UseStandardCommands>false</UseStandardCommands>
<Characteristics/>
<QuickChoice>true</QuickChoice>
<ChoiceMode>BothWays</ChoiceMode>
<DefaultListForm/>
<DefaultChoiceForm/>
<AuxiliaryListForm/>
<AuxiliaryChoiceForm/>
<ListPresentation/>
<ExtendedListPresentation/>
<Explanation/>
<ChoiceHistoryOnInput>Auto</ChoiceHistoryOnInput>
</Properties>
<ChildObjects>
<EnumValue uuid="4089864a-2bf2-4922-b485-7e7751dafd2f">
<Properties>
<Name>Исходящий</Name>
<Synonym>
<v8:item>
<v8:lang>ru</v8:lang>
<v8:content>Исходящий</v8:content>
</v8:item>
</Synonym>
<Comment/>
</Properties>
</EnumValue>
<EnumValue uuid="2b79cd73-4039-40e2-87cc-845401beac8e">
<Properties>
<Name>Входящий</Name>
<Synonym>
<v8:item>
<v8:lang>ru</v8:lang>
<v8:content>Входящий</v8:content>
</v8:item>
</Synonym>
<Comment/>
</Properties>
</EnumValue>
<EnumValue uuid="1475f3e9-3b55-4fca-baea-975a0f14ad7e">
<Properties>
<Name>Служебный</Name>
<Synonym>
<v8:item>
<v8:lang>ru</v8:lang>
<v8:content>Служебный</v8:content>
</v8:item>
</Synonym>
<Comment/>
</Properties>
</EnumValue>
</ChildObjects>
</Enum>
</MetaDataObject>

View File

@ -160,6 +160,30 @@
<Comment/>
</Properties>
</EnumValue>
<EnumValue uuid="2c1d93db-ac2f-4691-8a12-692f951bae4b">
<Properties>
<Name>Служебный</Name>
<Synonym>
<v8:item>
<v8:lang>ru</v8:lang>
<v8:content>Служебный</v8:content>
</v8:item>
</Synonym>
<Comment/>
</Properties>
</EnumValue>
<EnumValue uuid="da42d75a-deb5-4095-a4e6-2e5c319cc058">
<Properties>
<Name>ОшибкаСлужебного</Name>
<Synonym>
<v8:item>
<v8:lang>ru</v8:lang>
<v8:content>Ошибка служебного</v8:content>
</v8:item>
</Synonym>
<Comment/>
</Properties>
</EnumValue>
</ChildObjects>
</Enum>
</MetaDataObject>

View File

@ -18,6 +18,7 @@
<Content>
<xr:Item xsi:type="xr:MDObjectRef">CommonModule.пбп_ЗагрузкаФайлаЧерезТабличныйДокументВызовСервера</xr:Item>
<xr:Item xsi:type="xr:MDObjectRef">CommonModule.пбп_ЗагрузкаФайлаЧерезТабличныйДокументКлиент</xr:Item>
<xr:Item xsi:type="xr:MDObjectRef">CommonModule.пбп_ЗагрузкаФайлаЧерезТабличныйДокументСервер</xr:Item>
</Content>
</Properties>
<ChildObjects/>

View File

@ -49,6 +49,7 @@
<xr:Item xsi:type="xr:MDObjectRef">Role.пбп_ПросмотрИсторииИнтеграции</xr:Item>
<xr:Item xsi:type="xr:MDObjectRef">CommonModule.пбп_ИнтеграцииСлужебный</xr:Item>
<xr:Item xsi:type="xr:MDObjectRef">CommonModule.пбп_ИнтеграцииFTPSFTP</xr:Item>
<xr:Item xsi:type="xr:MDObjectRef">Enum.пбп_НаправленияИнтеграционныхПотоков</xr:Item>
</Content>
</Properties>
<ChildObjects/>