//ирПортативный Перем ирПортативный Экспорт; //ирПортативный Перем ирОбщий Экспорт; //ирПортативный Перем ирСервер Экспорт; //ирПортативный Перем ирКэш Экспорт; //ирПортативный Перем ирПривилегированный Экспорт; // Структура примитивных типов (Булево, Дата, Строка, Число) Перем ПримитивныеТипы; Перем мИмяКолонкиНомерСтроки Экспорт; Перем мИмяКолонкиРезультатПоиска Экспорт; Перем мИмяКолонкиРезультатЗаписи Экспорт; Перем мИмяКолонкиСообщенияОбработки Экспорт; Перем мАлгоритмКонвертацииЗначенияПараметры Экспорт; Перем мЭтоСсылочныйОбъект Экспорт; Перем мПлатформа Экспорт; Перем мКоличествоУспешно Экспорт; Перем мКоличествоНеуспешно Экспорт; Перем мТекущееПолноеИмяТаблицы Экспорт; Перем мКонсольЗапросов Экспорт; Перем мДополнениеЗапросом Экспорт; Перем мСуффиксСырыхДанных Экспорт; // Выводит сообщение об ошибке и выставляет параметр Отказ в "Истина". // В случае работы на клиенте или на сервере выводит в окно сообщений, // в случае внешнего соединения вызывает исключение. // // Параметры: // ТекстСообщения - строка, текст сообщения. // Отказ - булево, признак отказа (необязательный). // Функция ПолучитьПричинуОшибки(ТекстСообщения, Отказ = Ложь, Заголовок = "") Экспорт НачалоСлужебногоСообщения = Найти(ТекстСообщения, "{"); ОкончаниеСлужебногоСообщения = Найти(ТекстСообщения, "}:"); Если ОкончаниеСлужебногоСообщения > 0 И НачалоСлужебногоСообщения > 0 Тогда ТекстСообщения = Лев(ТекстСообщения, (НачалоСлужебногоСообщения - 1)) + Сред(ТекстСообщения, (ОкончаниеСлужебногоСообщения + 2)); КонецЕсли; Отказ = Истина; Возврат ТекстСообщения; КонецФункции Функция мПривестиКУникальномуИдентификатору(Представление, Примечание = "") Попытка Результат = Новый УникальныйИдентификатор(Представление); Исключение Примечание = "Неправильный формат уникального идентификатора"; КонецПопытки; Возврат Результат; КонецФункции Функция мПривестиКОписаниюТипов(Представление, Примечание = "") Попытка Результат = Новый ОписаниеТипов(Представление); Исключение Примечание = "Неправильный формат описания типов"; КонецПопытки; Возврат Результат; КонецФункции // Функция вычисляет значение ячейки для режима "Вычислять" // // Параметры: // Алгоритм - програмный код, который необходимо выполнить // ТекущиеДанные - структура загруженных значений // ТекстЯчейки - текст текущей ячейки // ТекстыЯчеек - массив текстов ячеек строки // Результат - результат вычисления // // Возвращаемое значение: // Структура, сордержащая Результат и ОписаниеОшибки Функция ВычислитьЗначениеЯчейки(Знач АлгоритмОбъект, Знач ТекущиеДанные, Знач ТекстЯчейки, Знач ТекстыЯчеек, Знач Результат, Знач ОписаниеОшибки = "", СтандартнаяОбработка = Истина) #Если Сервер И Не Сервер Тогда мПлатформа = Обработки.ирПлатформа.Создать(); #КонецЕсли ТекстЯчейки = СокрЛП(ТекстЯчейки); Попытка мПлатформа.ВыполнитьМетодАлгоритма(АлгоритмОбъект, 0, Результат, ТекстЯчейки, ТекстыЯчеек, ТекущиеДанные, ОписаниеОшибки, СтандартнаяОбработка); Исключение ОписаниеОшибки = ПолучитьПричинуОшибки(ОписаниеОшибки()); КонецПопытки; Возврат Новый Структура("Результат, ТекстЯчейки, ОписаниеОшибки, СтандартнаяОбработка", Результат, ТекстЯчейки, ОписаниеОшибки, СтандартнаяОбработка); КонецФункции // Функция записывает объект в информационную базу данных, используя // события определенные пользователем в форме редактирования событий // // Параметры: // Объект - записываемый объект // ТекстыЯчеек - массив текстов ячеек, загружаемой строки // // Возвращаемое значение: // Истина, если объект записан, Ложь - иначе // Функция ЗаписатьОбъект(ОбъектБД, выхОписаниеОшибки, СтрокиТаблицыБД) Отказ = Ложь; НачатьТранзакцию(); Успех = ирОбщий.ОбработатьСобытиеЛкс(СобытияОбработкиОбъектов, Метаданные().Макеты.АлгоритмПередЗаписьюОбъекта.Имя, выхОписаниеОшибки,, ОбъектБД.Данные, ОбъектБД.Методы, Отказ); Если Не Успех Тогда Отказ = Истина; КонецЕсли; Если Не Отказ Тогда Попытка ирОбщий.ЗаписатьОбъектЛкс(ОбъектБД.Методы); ИмяПоляСсылка = ""; Для каждого СтрокаСопоставленияБД Из СопоставлениеКолонокБД Цикл Если Истина И ЗначениеЗаполнено(СтрокаСопоставленияБД.ДопРеквизит) И СтрокаСопоставленияБД.ДоступноИзменение И СтрокаСопоставленияБД.Пометка Тогда НовоеЗначение = СтрокиТаблицыБД[0][СтрокаСопоставленияБД.ИмяКолонкиПриемника]; ирОбщий.УстановитьЗначениеДопРеквизитаБСПЛкс(ОбъектБД.Методы, СтрокаСопоставленияБД.ДопРеквизит, НовоеЗначение, ИмяПоляСсылка, Ложь, Истина); КонецЕсли; КонецЦикла; Исключение Отказ = Истина; выхОписаниеОшибки = ОписаниеОшибки(); КонецПопытки; КонецЕсли; Если Не Отказ Тогда Успех = ирОбщий.ОбработатьСобытиеЛкс(СобытияОбработкиОбъектов, Метаданные().Макеты.АлгоритмПриЗаписиОбъекта.Имя, выхОписаниеОшибки,, ОбъектБД.Данные, ОбъектБД.Методы, Отказ); Если Не Успех Тогда Отказ = Истина; КонецЕсли; КонецЕсли; Если Не Отказ Тогда ЗафиксироватьТранзакцию(); Иначе //выхОписаниеОшибки = ПолучитьПричинуОшибки(выхОписаниеОшибки); // https://www.hostedredmine.com/issues/891037 ОтменитьТранзакцию(); КонецЕсли; Возврат Не Отказ; КонецФункции #Если Клиент Тогда Процедура УстановитьИсточник() Экспорт мКонсольЗапросов = Неопределено; ЭтотОбъект.ПредставлениеТаблицы = ""; ЭтотОбъект.мЭтоСсылочныйОбъект = Ложь; МетаданныеИсточника = МетаданныеТаблицыБД(); Если МетаданныеИсточника <> Неопределено Тогда ЭтотОбъект.ПредставлениеТаблицы = МетаданныеИсточника.Представление(); ЭтотОбъект.мЭтоСсылочныйОбъект = ирОбщий.ЛиМетаданныеСсылочногоОбъектаЛкс(МетаданныеИсточника); ИначеЕсли ЗначениеЗаполнено(ПолноеИмяТаблицы) Тогда Если Не ирОбщий.ЛиТаблицаБДСуществуетЛкс(ПолноеИмяТаблицы) Тогда ирОбщий.СообщитьЛкс("Таблица БД " + ПолноеИмяТаблицы + " не найдена"); ЭтотОбъект.ПолноеИмяТаблицы = ""; КонецЕсли; КонецЕсли; Если Ложь Или ТаблицаЗначений.Колонки.Количество() < 2 Или (Истина И ТаблицаЗначений.Колонки.Количество() <= 2 И ЗначениеЗаполнено(ПолноеИмяТаблицы)) Тогда ОбновитьКолонкиТаблицыЗначений(, ЗначениеЗаполнено(ПолноеИмяТаблицы)); КонецЕсли; СопоставлениеКолонокТЗЗаполнить(); ЗаполнитьСопоставлениеКолонокБД(); Если ТабличныйДокумент.ВысотаТаблицы <= СтрокаЗаголовковТД Тогда ОбновитьДанныеТабличногоДокумента(Истина); КонецЕсли; мТекущееПолноеИмяТаблицы = ПолноеИмяТаблицы; КонецПроцедуры // Процедура выполняет контроль заполнения данных табличного документа // сообщает об ошибках и устанавливает коментарии к ошибочным ячейкам // // Параметры: // ТабличныйДокумент - ТабличныйДокумент, у которого необходимо сформировать шапку // Процедура КонтрольЗаполнения() Экспорт СтруктураПозицийТД = СтруктураПозицийТД(); КоличествоЭлементов = ТабличныйДокумент.ВысотаТаблицы - СтруктураПозицийТД.НомерСтрокиДанных + 1; ОчиститьСообщения(); ВычислитьЗависимостиКонвертации(); Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(КоличествоЭлементов, "Контроль заполнения"); КоличествоОшибокКонвертации = 0; КэшПоиска = Неопределено; Для К = 0 По КоличествоЭлементов - 1 Цикл ирОбщий.ОбработатьИндикаторЛкс(Индикатор); КонвертироватьСтрокуТД(ТабличныйДокумент, К + СтруктураПозицийТД.НомерСтрокиДанных,, КоличествоОшибокКонвертации,, КэшПоиска); КонецЦикла; ирОбщий.ОсвободитьИндикаторПроцессаЛкс(, Истина); СообщитьИтогиКонвертации(КоличествоОшибокКонвертации); КонецПроцедуры // Функция считывает в табличный документ данные из файла в формате Excel // // Параметры: // ТабличныйДокумент - ТабличныйДокумент, в который необходимо прочитать данные // ИмяФайла - имя файла в формате Excel, из которого необходимо прочитать данные // НомерЛистаExcel - номер листа книги Excel, из которого необходимо прочитать данные // // Возвращаемое значение: // Истина, если файл прочитан, Ложь - иначе // Функция _мПрочитатьТабличныйДокументИзExcel(ТабличныйДокумент, ИмяФайла, НомерЛистаExcel = 1) Экспорт #Если Сервер И Не Сервер Тогда ТабличныйДокумент = Новый ТабличныйДокумент; #КонецЕсли xlLastCell = 11; ВыбФайл = Новый Файл(ИмяФайла); Если НЕ ВыбФайл.Существует() Тогда ирОбщий.СообщитьЛкс("Файл не существует!"); Возврат Ложь; КонецЕсли; Попытка Excel = Новый COMОбъект("Excel.Application"); Excel.WorkBooks.Open(ИмяФайла); Состояние("Обработка файла Microsoft Excel..."); ExcelЛист = Excel.Sheets(НомерЛистаExcel); Исключение ирОбщий.СообщитьЛкс("Ошибка. Возможно неверно указан номер листа книги Excel."); Возврат ложь; КонецПопытки; ТабличныйДокумент.Очистить(); ActiveCell = Excel.ActiveCell.SpecialCells(xlLastCell); RowCount = ActiveCell.Row; ColumnCount = ActiveCell.Column; Для Column = 1 По ColumnCount Цикл ТабличныйДокумент.Область("C" + Формат(Column, "ЧГ=")).ШиринаКолонки = ExcelЛист.Columns(Column).ColumnWidth; КонецЦикла; Для Row = 1 По RowCount Цикл Для Column = 1 По ColumnCount Цикл ТабличныйДокумент.Область("R" + Формат(Row, "ЧГ=") +"C" + Формат(Column, "ЧГ=")).Текст = ExcelЛист.Cells(Row,Column).Text; КонецЦикла; КонецЦикла; Excel.WorkBooks.Close(); Excel = 0; Возврат Истина; КонецФункции // () // Функция интерактивно предлагает выбрать значение в зависимости от переданных параметров // В форме, в списке выбора или выдает сообщение, что "Данная ячейка не может содержать значение" // // Параметры: // Значение - значение, которое необходимо выбрать // ОписаниеТипов - Описание типов выбираемого значения // СвязьПоТипу - ПВХ связи значения по типу // ЭлементСвязиПоТипу - номер элемента связи по типу // // Возвращаемое значение: // Истина - значение выбрано, ложь - иначе. // Функция мВыбратьЗначение(Значение, ОписаниеТипов, СвязьПоТипу, ЭлементСвязиПоТипу, СвязьПоВладельцу, ВыборГруппы = Ложь, Знач СоздатьОбъект = Ложь, Знач ИскатьПо = "") Если СвязьПоТипу = Неопределено Тогда Типы = ОписаниеТипов; Иначе ВидыСубконто = СвязьПоТипу.ВидыСубконто; Если ЭлементСвязиПоТипу > ВидыСубконто.Количество() Тогда Предупреждение("Данная ячейка не может содержать значение"); Возврат ложь; КонецЕсли; Типы = СвязьПоТипу.ВидыСубконто[ЭлементСвязиПоТипу-1].ВидСубконто.ТипЗначения; КонецЕсли; Если Типы.Типы().Количество() = 1 Тогда Тип = Типы.Типы()[0]; Если Истина И СоздатьОбъект И Не ирОбщий.ЛиТипСсылкиБДЛкс(Тип) Тогда Возврат Ложь; КонецЕсли; Менеджер = ирОбщий.ПолучитьМенеджерЛкс(Тип); Если Менеджер = Неопределено Тогда Возврат ВвестиЗначение(Значение,,Типы); Иначе //Если Справочники.ТипВсеСсылки().СодержитТип(Тип) Тогда // Если ВыборГруппы Тогда // ФормаВыбора = Менеджер.ПолучитьФормуВыбораГруппы(); // Иначе // ФормаВыбора = Менеджер.ПолучитьФормуВыбора(); // КонецЕсли; // ФормаВыбора.ПараметрВыборПоВладельцу = СвязьПоВладельцу; // ФормаВыбора.ПараметрОтборПоВладельцу = СвязьПоВладельцу; //Иначе // ФормаВыбора = Менеджер.ПолучитьФормуВыбора(); //КонецЕсли; //ФормаВыбора.НачальноеЗначениеВыбора = Значение; //Значение = ФормаВыбора.ОткрытьМодально(); Отбор = Новый Структура(); Если ЗначениеЗаполнено(СвязьПоВладельцу) Тогда Отбор.Вставить("Владелец", СвязьПоВладельцу); КонецЕсли; Если ВыборГруппы Тогда Отбор.Вставить("ЭтоГруппа", Истина); КонецЕсли; Если СоздатьОбъект И Не ирОбщий.ЛиТипТаблицыМетассылкиЛкс(Тип) Тогда СтруктураОбъекта = ирОбщий.ОбъектБДПоКлючуЛкс(Метаданные.НайтиПоТипу(Тип).ПолноеИмя(), ВыборГруппы); Если Не ЗначениеЗаполнено(ИскатьПо) Тогда ИскатьПо = "Наименование"; КонецЕсли; Отбор.Вставить(ИскатьПо, Значение); ЗаполнитьЗначенияСвойств(СтруктураОбъекта.Данные, Отбор); Форма = ирОбщий.ОткрытьОбъектВРедактореОбъектаБДЛкс(СтруктураОбъекта,,, Истина); Значение = Форма.ВыбОбъект; Иначе Если ирОбщий.ЛиСсылкаНаОбъектБДЛкс(Значение) Тогда ТекущаяСтрока = Значение; КонецЕсли; Значение = ирОбщий.ОткрытьФормуСпискаЛкс(Тип, Отбор,,, Истина,, ТекущаяСтрока, Истина); КонецЕсли; Возврат ЗначениеЗаполнено(Значение); КонецЕсли; Иначе ФормаВыбораЗначения = ПолучитьФорму("ФормаВыбораЗначения"); ФормаВыбораЗначения.ЭлементыФормы.Значение.ВыборПоВладельцу = СвязьПоВладельцу; ФормаВыбораЗначения.ЭлементыФормы.Значение.ТипЗначения = ОписаниеТипов; ФормаВыбораЗначения.ЭлементыФормы.Значение.ОграничениеТипа = Типы; ФормаВыбораЗначения.ЭлементыФормы.Значение.ЭлементСвязиПоТипу = ЭлементСвязиПоТипу; ФормаВыбораЗначения.ЭлементыФормы.Значение.Значение = Значение; Значение = ФормаВыбораЗначения.ОткрытьМодально(); Возврат Не Значение = Неопределено; КонецЕсли; КонецФункции // Функция интерактивно предлагает выбрать значение в текущей ячейке табличного документа // // Параметры: // ТабличныйДокумент - ТабличныйДокумент, в текущей ячейке которого необходимо выбрать значение // // Возвращаемое значение: // Истина, если значение выбрано, Ложь - иначе // Процедура ВыбратьЗначениеВЯчейке(СоздатьОбъект = Ложь) Экспорт ОчиститьСообщения(); ТекущаяОбласть = ТабличныйДокумент.ТекущаяОбласть; Если ТекущаяОбласть.Верх <> ТекущаяОбласть.Низ Или ТекущаяОбласть.Лево <> ТекущаяОбласть.Право Тогда Предупреждение("Для непосредственного выбора значения необходимо выбирать только одну ячейку"); Возврат; КонецЕсли; ТекущаяКолонка = СтрокаСопоставленияКолонкиТЗДляОбластиТД(ТекущаяОбласть); Если ТекущаяКолонка = Неопределено Тогда Предупреждение("Значение данной колонки не выбирается"); Возврат; КонецЕсли; ВычислитьЗависимостиКонвертации(); ТекущаяСтрока = КонвертироватьСтрокуТД(ТабличныйДокумент, ТекущаяОбласть.Верх); Значение = ТекущаяОбласть.Расшифровка; Если ТипЗнч(Значение) = Тип("СписокЗначений") И Значение.Количество() > 0 Тогда Значение = Значение[0].Значение; КонецЕсли; Если Не ирОбщий.ЛиСсылкаНаОбъектБДЛкс(Значение) Тогда Значение = ТекущаяОбласть.Текст; КонецЕсли; СвязьПоТипу = Неопределено; Если Не ПустаяСтрока(ТекущаяКолонка.СвязьПоТипу) Тогда Если ТипЗНЧ(ТекущаяКолонка.СвязьПоТипу) = Тип("Строка") Тогда ТекущаяСтрока.Свойство(ТекущаяКолонка.СвязьПоТипу,СвязьПоТипу); Иначе СвязьПоТипу = ТекущаяКолонка.СвязьПоТипу; КонецЕсли; КонецЕсли; СвязьПоВладельцу = Неопределено; Если Не ПустаяСтрока(ТекущаяКолонка.СвязьПоВладельцу) Тогда Если ТипЗНЧ(ТекущаяКолонка.СвязьПоВладельцу) = Тип("Строка") Тогда ТекущаяСтрока.Свойство(ТекущаяКолонка.СвязьПоВладельцу,СвязьПоВладельцу); Иначе СвязьПоВладельцу = ТекущаяКолонка.СвязьПоВладельцу; КонецЕсли; КонецЕсли; ЭлементСвязиПоТипу = ?(ТекущаяКолонка.ЭлементСвязиПоТипу = 0,1,ТекущаяКолонка.ЭлементСвязиПоТипу); Если мВыбратьЗначение(Значение, ТекущаяКолонка.ОписаниеТипов, СвязьПоТипу, ЭлементСвязиПоТипу, СвязьПоВладельцу, ТекущаяКолонка.ИмяКолонкиПриемника = "Родитель", СоздатьОбъект, ТекущаяКолонка.ИскатьПо) Тогда ТекущаяОбласть.Расшифровка = Значение; Если ТекущаяОбласть.СодержитЗначение Тогда ТекущаяОбласть.СодержитЗначение = Ложь; КонецЕсли; Если ПустаяСтрока(ТекущаяКолонка.ИскатьПо) Или ТекущаяКолонка.ИскатьПо = "Синоним" Тогда ТекущаяОбласть.Текст = Строка(Значение); Иначе ТекущаяОбласть.Текст = Строка(Значение[ТекущаяКолонка.ИскатьПо]); КонецЕсли; ТекущаяОбласть.Примечание.Текст = ""; ОчиститьСообщения(); КонвертироватьСтрокуТД(ТабличныйДокумент, ТекущаяОбласть.Верх); КонецЕсли; КонецПроцедуры // () // Процедура обновляет содержимое табличного документа, в соответствии с таблицей загружаемых реквизитов // // Параметры: // ТабличныйДокумент - ТабличныйДокумент, который необходимо обновить // БезВопросов - булево, если Ложь, спрашивать об очистке табличного документа, если он не пустой, Истина - иначе // Процедура ОбновитьДанныеТабличногоДокумента(БезВопросов = Ложь) Экспорт #Если Сервер И Не Сервер Тогда ТабличныйДокумент = Новый ТабличныйДокумент; #КонецЕсли Если ТабличныйДокумент.ВысотаТаблицы > 1 И Не БезВопросов Тогда Результат = Вопрос("Табличный документ содержит данные. Очистить?", РежимДиалогаВопрос.ДаНетОтмена, , КодВозвратаДиалога.Нет); Если Результат = КодВозвратаДиалога.Да Тогда ТабличныйДокумент.Очистить(); ИначеЕсли Результат = КодВозвратаДиалога.Отмена Тогда Возврат; Иначе СтруктураПозицийТД = СтруктураПозицийТД(Истина); Для К = 1 По ТабличныйДокумент.ШиринаТаблицы Цикл ТабличныйДокумент.Область(СтруктураПозицийТД.НомерСтрокиЗаголовков, К).Текст = ""; КонецЦикла; КонецЕсли; Иначе ТабличныйДокумент.Очистить(); КонецЕсли; Если ТабличныйДокумент.ВысотаТаблицы = 0 Тогда ЭтотОбъект.СтрокаЗаголовковТД = 0; ЭтотОбъект.ПерваяСтрокаДанныхТД = 0; ЭтотОбъект.ПоследняяСтрокаДанныхТД = 0; КонецЕсли; //СформироватьСтруктуруКолонок(); СформироватьШапкуТабличногоДокумента(СтруктураПозицийТД); КонецПроцедуры #КонецЕсли // Конвертирует значения из табличного документа в таблицу значений // // Параметры внутри Параметры: // СтруктураПозицийТД - Структура - // НачальнаяСтрока - Число - // КонечнаяСтрока - Число - // *ЭтаФорма - Форма - указывается форма этого инструмента для синхронного отображения первых сконвертированных строк // // Возвращаемое значение: // Истина, если - загрузка прошла без ошибок, Ложь - иначе // Функция КонвертироватьДанные(Параметры = Неопределено) Экспорт #Если Сервер И Не Сервер Тогда ТабличныйДокумент = Новый ТабличныйДокумент; #КонецЕсли КэшПоиска = Неопределено; КоличествоОшибокКонвертации = 0; Если Параметры <> Неопределено Тогда ЭтотОбъект.ВыполнятьКонвертациюНаСервере = Параметры.ВыполнятьНаСервере; НачальнаяСтрока = Параметры.НачальнаяСтрока; КонечнаяСтрока = Параметры.КонечнаяСтрока; СтруктураПозицийТД = Параметры.СтруктураПозицийТД; ЭтаФорма = Параметры.ЭтаФорма; #Если Сервер И Не Сервер Тогда ЭтаФорма = ОткрытьФорму(); #КонецЕсли КонецЕсли; Если СтруктураПозицийТД = Неопределено Тогда СтруктураПозицийТД = СтруктураПозицийТД(, Истина); КонецЕсли; Если Не ЗначениеЗаполнено(НачальнаяСтрока) Тогда НачальнаяСтрока = СтруктураПозицийТД.НомерСтрокиДанных; КонечнаяСтрока = ТабличныйДокумент.ВысотаТаблицы; КонецЕсли; КоличествоЭлементов = КонечнаяСтрока - НачальнаяСтрока + 1; Если КоличествоЭлементов <= 0 Тогда Успех = Ложь; ирОбщий.СообщитьЛкс("Нет данных для конвертации. Задайте ""Начало данных"" на странице ""Табличный документ"""); Иначе Успех = Истина; СоответствиеКолонок = ПолучитьКолонкиТабличногоДокумента(СтруктураПозицийТД); ТаблицаЗначений.Очистить(); ОшибкиКонвертации.Очистить(); ДобавитьСырыеКолонкиВТЗ(); Если ЭтаФорма <> Неопределено Тогда ЭтаФорма.ТаблицаЗначенийОтобранное = ТаблицаЗначений; ЭтаФорма.ОбновитьКолонкиТабличногоПоляТаблицыЗначений(); ЭтаФорма.ТаблицаЗначенийОтобранное = ТаблицаЗначений; ЭтаФорма.ТекущийЭлемент = ЭтаФорма.ЭлементыФормы.ТаблицаЗначений; ЭтаФорма.ЭлементыФормы.ТаблицаЗначений.ОбновитьСтроки(); КонецЕсли; ВычислитьЗависимостиКонвертации(); ЛиПервыеСтрокиОтображены = Ложь; Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(КоличествоЭлементов, "Конвертация ТД => ТЗ"); Для НомерСтроки = НачальнаяСтрока По КонечнаяСтрока Цикл Если ирОбщий.ОбработатьИндикаторЛкс(Индикатор) Тогда Если Истина И ЭтаФорма <> Неопределено И (Ложь Или Не ЛиПервыеСтрокиОтображены Или ТаблицаЗначений.Количество() < 40) Тогда ЭтаФорма.ЭлементыФормы.ТаблицаЗначений.ОбновитьСтроки(); ЛиПервыеСтрокиОтображены = Истина; КонецЕсли; КонецЕсли; ТекущаяСтрока = КонвертироватьСтрокуТД(ТабличныйДокумент, НомерСтроки, , КоличествоОшибокКонвертации, Истина, КэшПоиска); #Если Сервер И Не Сервер Тогда ТекущаяСтрока = Новый Структура; #КонецЕсли СтрокаДанных = ТаблицаЗначений.Добавить(); СтрокаДанных[мИмяКолонкиНомерСтроки] = НомерСтроки; Для каждого КлючИЗначение Из ТекущаяСтрока Цикл СтрокаДанных[КлючИЗначение.Ключ] = КлючИЗначение.Значение; КонецЦикла; КонецЦикла; ирОбщий.ОсвободитьИндикаторПроцессаЛкс(, Истина); // Сужаем квалификаторы чисел и строк, игнорируя сопоставленные с БД колонки ИгнорироватьКолонки = СопоставлениеКолонокБД.ВыгрузитьКолонку("ИмяКолонкиИсточника"); ИгнорироватьКолонки.Добавить(мИмяКолонкиНомерСтроки); ЭтотОбъект.ТаблицаЗначений = ирОбщий.СузитьТипыКолонокТаблицыБезПотериДанныхЛкс(ТаблицаЗначений,,,,, Истина, ИгнорироватьКолонки); СообщитьИтогиКонвертации(КоличествоОшибокКонвертации); КонецЕсли; Результат = Новый Структура(); Результат.Вставить("ТаблицаЗначений", ТаблицаЗначений); Результат.Вставить("Успех", Успех); Результат.Вставить("ОшибкиКонвертации", ОшибкиКонвертации.Выгрузить()); Результат.Вставить("КоличествоОшибокКонвертации", КоличествоОшибокКонвертации); #Если Не Клиент Тогда Если КоличествоОшибокКонвертации > 0 Тогда Результат.Вставить("ТабличныйДокумент", ТабличныйДокумент); КонецЕсли; #КонецЕсли Возврат Результат; КонецФункции Процедура ДобавитьСырыеКолонкиВТЗ() Экспорт Если ДобавлятьСырыеДанныеВТЗ Тогда Для каждого СтрокаСопоставления Из СопоставлениеКолонокТЗ.НайтиСтроки(Новый Структура("Пометка", Истина)) Цикл Если СтрокаСопоставления.РежимКонвертации = "Устанавливать" Тогда Продолжить; КонецЕсли; ИмяСыройКолонки = СтрокаСопоставления.ИмяКолонкиПриемника + мСуффиксСырыхДанных; Если ТаблицаЗначений.Колонки.Найти(ИмяСыройКолонки) = Неопределено Тогда КонвертированнаяКолонка = ТаблицаЗначений.Колонки.Найти(СтрЗаменить(ИмяСыройКолонки, мСуффиксСырыхДанных, "")); Если КонвертированнаяКолонка = Неопределено Тогда Продолжить; // КонецЕсли; ТаблицаЗначений.Колонки.Добавить(ИмяСыройКолонки, Новый ОписаниеТипов("Строка"), КонвертированнаяКолонка.Заголовок + ". Сырое"); КонецЕсли; КонецЦикла; КонецЕсли; КонецПроцедуры Процедура ВычислитьЗависимостиКонвертации() КолонкаЗависимая = СопоставлениеКолонокТЗ.Колонки.Найти("Зависимая"); Если КолонкаЗависимая = Неопределено Тогда СопоставлениеКолонокТЗ.Колонки.Добавить("Зависимая", Новый ОписаниеТипов("Булево")); КонецЕсли; Для Каждого СтрокаСопоставления Из СопоставлениеКолонокТЗ Цикл СтрокаСопоставления.Зависимая = Ложь Или ТипЗнч(СтрокаСопоставления.СвязьПоТипу) = Тип("Строка") И ЗначениеЗаполнено(СтрокаСопоставления.СвязьПоТипу) Или ТипЗнч(СтрокаСопоставления.СвязьПоВладельцу) = Тип("Строка") И ЗначениеЗаполнено(СтрокаСопоставления.СвязьПоВладельцу); СтрокаСопоставления.СодержитСсылки = Ложь Или СтрокаСопоставления.ОписаниеТипов.Типы().Количество() = 0 Или ирОбщий.ЛиОписаниеТиповПростогоСсылочногоТипаЛкс(СтрокаСопоставления.ОписаниеТипов,, Ложь); КонецЦикла; КонецПроцедуры // Функция возвращает метаданные источника данных // // Параметры: // нет // // Возвращаемое значение: // Объект метаданных // Функция МетаданныеТаблицыБД() Экспорт Результат = ирОбщий.ОбъектМДПоПолномуИмениТаблицыБДЛкс(ПолноеИмяТаблицы); Возврат Результат; КонецФункции // Функция возвращает значение структуры "Колонки" по области табличного документа, // содержащее описание свойств колонки // // Параметры: // область - область табличного документа // // Возвращаемое значение: // значение структуры "Колонки" // Функция СтрокаСопоставленияКолонкиТЗДляОбластиТД(Область) Экспорт Для каждого СтрокаСопоставления Из СопоставлениеКолонокТЗ Цикл Если Область.Лево = Число(СтрокаСопоставления.ИмяКолонкиИсточника) Тогда Возврат СтрокаСопоставления; КонецЕсли; КонецЦикла; Возврат Неопределено; КонецФункции // () // Процедура формирует шапку табличного документа, в соответствии с таблицей загружаемых реквизитов // // Параметры: // ТабличныйДокумент - ТабличныйДокумент, у которого необходимо сформировать шапку // Процедура СформироватьШапкуТабличногоДокумента(СтруктураПозицийТД = Неопределено) Экспорт Линия = Новый Линия(ТипЛинииЯчейкиТабличногоДокумента.Сплошная, 1); Таблица = СопоставлениеКолонокТЗ.Скопировать(); Таблица.Сортировать("ИмяКолонкиИсточника"); ОбластьШапкиЭталон = Неопределено; Для каждого СтрокаСопоставления Из СопоставлениеКолонокТЗ Цикл НомерКолонки = СтрокаСопоставления.ИмяКолонкиИсточника; Если Не СтрокаСопоставления.Пометка Тогда Продолжить; КонецЕсли; Если Не ЗначениеЗаполнено(НомерКолонки) Тогда Для Счетчик = 1 По СопоставлениеКолонокТЗ.Количество() Цикл Если СопоставлениеКолонокТЗ.Найти(ИмяКолонкиТабличногоДокумента(Счетчик), "ИмяКолонкиИсточника") = Неопределено Тогда НомерКолонки = Счетчик; Прервать; КонецЕсли; КонецЦикла; Если Не ЗначениеЗаполнено(НомерКолонки) Тогда Продолжить; КонецЕсли; ОписаниеКолонки = Новый Структура("Имя, Заголовок, ПримерДанных", ИмяКолонкиТабличногоДокумента(НомерКолонки), СтрокаСопоставления.СинонимКолонкиПриемника, ""); СопоставитьКолонкуТЗ(СтрокаСопоставления, ОписаниеКолонки); КонецЕсли; Если СтрокаСопоставления.ШиринаКолонки = 0 Тогда ШиринаКолонки = 20; Если СтрокаСопоставления.ОписаниеТипов.Типы().Количество() = 1 Тогда ПервыйТип = СтрокаСопоставления.ОписаниеТипов.Типы()[0]; Если ПервыйТип = Тип("Строка") Тогда Если СтрокаСопоставления.ОписаниеТипов.КвалификаторыСтроки.Длина = 0 Тогда ШиринаКолонки = 40; Иначе ШиринаКолонки = Мин(Макс(СтрокаСопоставления.ОписаниеТипов.КвалификаторыСтроки.Длина, 10), 40); КонецЕсли; ИначеЕсли ПервыйТип = Тип("Число") Тогда ШиринаКолонки = Макс(СтрокаСопоставления.ОписаниеТипов.КвалификаторыЧисла.Разрядность, 10); ИначеЕсли ПервыйТип = Тип("Булево") Тогда ШиринаКолонки = 10; КонецЕсли; КонецЕсли; Иначе ШиринаКолонки = СтрокаСопоставления.ШиринаКолонки; КонецЕсли; Если СтруктураПозицийТД = Неопределено Тогда СтруктураПозицийТД = СтруктураПозицийТД(Истина); КонецЕсли; ОбластьШапки = ТабличныйДокумент.Область(СтруктураПозицийТД.НомерСтрокиЗаголовков, НомерКолонки); БылТекст = Не ПустаяСтрока(ОбластьШапки.Текст); Если ОбластьШапкиЭталон = Неопределено Тогда ОбластьШапки.ЦветФона = ЦветаСтиля.ЦветФонаФормы; //Область.Обвести(Линия, Линия, Линия, Линия); ОбластьШапки.Шрифт = Новый Шрифт(,, Истина); ОбластьШапкиЭталон = ОбластьШапки; Иначе ЗаполнитьЗначенияСвойств(ОбластьШапки, ОбластьШапкиЭталон,, "Имя, Текст, Расшифровка, Примечание, ТипЗначения, ЭлементУправления"); КонецЕсли; ОбластьШапки.Текст = ?(БылТекст, ОбластьШапки.Текст + Символы.ПС,"") + СтрокаСопоставления.СинонимКолонкиПриемника; ОбластьШапки.Расшифровка = СтрокаСопоставления.ИмяКолонкиПриемника; ОбластьКолонки = ТабличныйДокумент.Область("C"+НомерКолонки); ОбластьКолонки.ШиринаКолонки = ?(БылТекст, Макс(ОбластьКолонки.ШиринаКолонки, ШиринаКолонки), ШиринаКолонки); КонецЦикла; //ОбновитьКолонкиТаблицыЗначений(, Ложь); КонецПроцедуры // Параметры: // ИзБД - Булево - Истина - из БД, иначе из табличного документа // Функция ОбновитьКолонкиТаблицыЗначений(Знач ОчиститьСуществующие = Ложь, Знач ИзБД = Истина, Знач СообщитьОДобавленииКолонокБД = Ложь) Экспорт КолонкиИзменены = Ложь; Если ОчиститьСуществующие Тогда ТаблицаЗначений.Очистить(); ТаблицаЗначений.Колонки.Очистить(); ЭтотОбъект.ТаблицаЗначенийИспользоватьОтбор = Ложь; Если АвтоДобавлениеКолонокТЗИзБД И ЗначениеЗаполнено(ПолноеИмяТаблицы) И Не ИзБД Тогда ОбновитьКолонкиТаблицыЗначений(Ложь, Истина, Истина); КонецЕсли; КолонкиИзменены = Истина; КонецЕсли; ПроверитьДобавитьКолонкуИдентификатораСтроки(ТаблицаЗначений); Если ИзБД Тогда Если ЗначениеЗаполнено(ПолноеИмяТаблицы) Тогда Если Истина И СопоставлениеКолонокБД.НайтиСтроки(Новый Структура("Пометка", Истина)).Количество() = 0 И СопоставлениеКолонокБД.НайтиСтроки(Новый Структура("ПолеПоиска", Истина)).Количество() = 0 И СопоставлениеКолонокБД.Количество() > 0 Тогда Если СопоставлениеКолонокБД.Количество() < 30 Тогда ирОбщий.СообщитьЛкс("Помечены все колонки БД, т.к. пользователь не пометил нужные"); ирОбщий.УстановитьСвойствоВКоллекцииЛкс(СопоставлениеКолонокБД.НайтиСтроки(Новый Структура("ДоступноИзменение", Истина)), "Пометка", Истина); ирОбщий.УстановитьСвойствоВКоллекцииЛкс(СопоставлениеКолонокБД.НайтиСтроки(Новый Структура("Ключевое", Истина)), "ПолеПоиска", Истина); ИначеЕсли ОчиститьСуществующие Тогда ирОбщий.СообщитьЛкс("Отсутствуют помеченные колонки БД"); КонецЕсли; КонецЕсли; КоличествоДобавлено = 0; Для каждого СтрокаСопоставленияБД Из СопоставлениеКолонокБД Цикл Если Не ПересоздатьКолонкуТЗПоКолонкеБД(СтрокаСопоставленияБД) Тогда Продолжить; КонецЕсли; СтрокаСопоставленияБД.Пометка = СтрокаСопоставленияБД.ДоступноИзменение; КоличествоДобавлено = КоличествоДобавлено + 1; КонецЦикла; Если КоличествоДобавлено > 10 И СообщитьОДобавленииКолонокБД И АвтоДобавлениеКолонокТЗИзБД Тогда ирОбщий.СообщитьЛкс("Помеченные колонки БД добавлены в таблицу значений из-за включенного флажка ""Авто колонки из БД"""); КонецЕсли; Если КоличествоДобавлено > 0 Тогда КолонкиИзменены = Истина; КонецЕсли; КонецЕсли; Иначе ПримитивныеТипыПоПриоритету = Новый Массив; ПримитивныеТипыПоПриоритету.Добавить("Булево"); ПримитивныеТипыПоПриоритету.Добавить("Число"); ПримитивныеТипыПоПриоритету.Добавить("Дата"); СтруктураПозицийТД = СтруктураПозицийТД(); СообщенияПользователю = Новый Массив; ИндикаторКолонок = ирОбщий.ПолучитьИндикаторПроцессаЛкс(ТабличныйДокумент.ШиринаТаблицы, "Анализ документа"); Для НомерКолонки = 1 По ТабличныйДокумент.ШиринаТаблицы Цикл ирОбщий.ОбработатьИндикаторЛкс(ИндикаторКолонок); СинонимКолонки = ""; Если ЗначениеЗаполнено(СтруктураПозицийТД.НомерСтрокиЗаголовков) Тогда СинонимКолонки = ТабличныйДокумент.Область(СтруктураПозицийТД.НомерСтрокиЗаголовков, НомерКолонки).Текст; КонецЕсли; Если Не ЗначениеЗаполнено(СинонимКолонки) Тогда СинонимКолонки = "Колонка " + Формат(НомерКолонки, "ЧЦ=3; ЧВН="); КонецЕсли; ИмяКолонки = ирОбщий.ИдентификаторИзПредставленияЛкс(СинонимКолонки); Если ТаблицаЗначений.Колонки.Найти(ИмяКолонки) <> Неопределено Тогда Продолжить; КонецЕсли; ШиринаКолонки = ТабличныйДокумент.Область(СтруктураПозицийТД.НомерСтрокиДанных, НомерКолонки).ШиринаКолонки; СтрокаСопоставленияБД = СопоставлениеКолонокБД.Найти(ИмяКолонки, "ИмяКолонкиПриемника"); ОписаниеТипов = Новый ОписаниеТипов; Если СтрокаСопоставленияБД <> Неопределено Тогда ОписаниеТипов = СтрокаСопоставленияБД.ОписаниеТиповПриемника; ИначеЕсли Ложь Тогда //Если ЛиВтораяСтрокаСодержитТипыЗначений Тогда ИменаТипов = ТабличныйДокумент.Область(2, НомерКолонки).Текст; Иначе ИменаТипов = Новый Массив; МаксДлинаСтроки = 0; УспешныеТипы = Новый Соответствие; НеуспешныеТипы = Новый Соответствие; Для Каждого ПримитивныйТип Из ПримитивныеТипы Цикл ПримитивныйТип = ПримитивныйТип.Ключ; УспешныеТипы[ПримитивныйТип] = 0; НеуспешныеТипы[ПримитивныйТип] = 0; КонецЦикла; НомерПоследнейСтроки = СтруктураПозицийТД.НомерПоследнейСтрокиДанных; Если ПоследняяСтрокаДанныхТД = 0 Тогда // Авторассчитанную последнюю строку не рассматриваем, если она не единственная, т.к. она может быть нежелательной НомерПоследнейСтроки = Макс(СтруктураПозицийТД.НомерСтрокиДанных, СтруктураПозицийТД.НомерПоследнейСтрокиДанных - 1); КонецЕсли; МоноНуль = Истина; НомерПоследнейСтроки = Мин(НомерПоследнейСтроки, СтруктураПозицийТД.НомерСтрокиДанных + 10000 / ТабличныйДокумент.ШиринаТаблицы); Для НомерСтроки = СтруктураПозицийТД.НомерСтрокиДанных По НомерПоследнейСтроки Цикл #Если Клиент Тогда ОбработкаПрерыванияПользователя(); #КонецЕсли ОбластьЯчейки = ТабличныйДокумент.Область(НомерСтроки, НомерКолонки); Если ОбластьЯчейки.Лево <> НомерКолонки Тогда // Не левая ячейка объединенной горизонтально области Продолжить; КонецЕсли; Расшифровка = ОбластьЯчейки.Расшифровка; Если Истина И Расшифровка <> Неопределено И ТипЗнч(Расшифровка) <> Тип("ИдентификаторРасшифровкиКомпоновкиДанных") Тогда ИменаТипов.Добавить(ТипЗнч(Расшифровка)); Если Расшифровка <> 0 Тогда МоноНуль = Ложь; КонецЕсли; Иначе ТекстЯчейки = СокрЛП(ОбластьЯчейки.Текст); Если ТекстЯчейки <> "0" Тогда МоноНуль = Ложь; КонецЕсли; Если ЗначениеЗаполнено(ТекстЯчейки) Тогда Для Каждого ПримитивныйТип Из ПримитивныеТипыПоПриоритету Цикл Если ПримитивныйТип = "Строка" Тогда Продолжить; ИначеЕсли ПримитивныйТип = "Дата" Тогда ТекстОшибки = ""; РезультатКонвертации = ирОбщий.СтрокаВДатуЛкс(ТекстЯчейки,, ТекстОшибки); Если ЗначениеЗаполнено(ТекстОшибки) Тогда РезультатКонвертации = Неопределено; КонецЕсли; ИначеЕсли ПримитивныйТип = "Число" Тогда ТекстОшибки = ""; РезультатКонвертации = ирОбщий.СтрокаВЧислоЛкс(ТекстЯчейки,, ТекстОшибки); Если ЗначениеЗаполнено(ТекстОшибки) Тогда РезультатКонвертации = Неопределено; КонецЕсли; ИначеЕсли Истина И ПримитивныйТип = "Булево" И (ТекстЯчейки = "0" Или ТекстЯчейки = "1") Тогда РезультатКонвертации = Истина; Иначе Попытка РезультатКонвертации = Вычислить(ПримитивныйТип + "(ТекстЯчейки)"); Исключение РезультатКонвертации = Неопределено; КонецПопытки; КонецЕсли; Если Истина И РезультатКонвертации <> Неопределено И Не (Истина И ПримитивныйТип = "Число" И Лев(ТекстЯчейки, 1) = "0" И СтрДлина(ТекстЯчейки) > 1 И Найти(ТекстЯчейки, ".") > 2) Тогда УспешныеТипы[ПримитивныйТип] = УспешныеТипы[ПримитивныйТип] + 1; Иначе НеуспешныеТипы[ПримитивныйТип] = НеуспешныеТипы[ПримитивныйТип] + 1; КонецЕсли; КонецЦикла; КонецЕсли; КонецЕсли; Если МаксДлинаСтроки < СтрДлина(ОбластьЯчейки.Текст) Тогда МаксДлинаСтроки = СтрДлина(ОбластьЯчейки.Текст); КонецЕсли; КонецЦикла; Если МоноНуль Тогда ИменаТипов.Добавить(Тип("Число")); Иначе Для Каждого ПримитивныйТип Из ПримитивныеТипыПоПриоритету Цикл Если УспешныеТипы[ПримитивныйТип] > 0 И НеуспешныеТипы[ПримитивныйТип] = 0 Тогда ИменаТипов.Добавить(Тип(ПримитивныйТип)); Прервать; КонецЕсли; КонецЦикла; КонецЕсли; Если ИменаТипов.Количество() = 0 Тогда ИменаТипов = "Строка"; КонецЕсли; Если МаксДлинаСтроки = 0 И ИменаТипов = "Строка" Тогда // Отказываемся от создания колонки ТЗ для пустой колонки ТД Продолжить; КонецЕсли; // ОписаниеТипов = Новый ОписаниеТипов(ИменаТипов,,,, Новый КвалификаторыСтроки(МаксДлинаСтроки)); // Теперь квалификаторы вычисляются после конвертации ОписаниеТипов = Новый ОписаниеТипов(ИменаТипов); КонецЕсли; КолонкаТЗ = ТаблицаЗначений.Колонки.Добавить(ИмяКолонки, ОписаниеТипов, СинонимКолонки, ШиринаКолонки); Если ЗначениеЗаполнено(ПолноеИмяТаблицы) Тогда Если СтрокаСопоставленияБД <> Неопределено Тогда СопоставитьКолонкуБД(СтрокаСопоставленияБД, КолонкаТЗ); Иначе СообщенияПользователю.Добавить(ИмяКолонки); КонецЕсли; КонецЕсли; КолонкиИзменены = Истина; КонецЦикла; ирОбщий.ОсвободитьИндикаторПроцессаЛкс(); Если СообщенияПользователю.Количество() > 0 Тогда СообщенияПользователю.Вставить(0, "--- Не сопоставлены с колонками БД созданные колонки таблицы значений:"); СообщенияПользователю.Добавить("- Рекомендуется сопоставить их вручную на странице ""Выбор колонок БД"""); ирОбщий.СообщитьЛкс(ирОбщий.СтрСоединитьЛкс(СообщенияПользователю, Символы.ПС)); КонецЕсли; КонецЕсли; Возврат КолонкиИзменены; КонецФункции Функция ПересоздатьКолонкуТЗПоКолонкеБД(Знач СтрокаСопоставленияБД) Экспорт Если ЗначениеЗаполнено(СтрокаСопоставленияБД.ИмяКолонкиИсточника) Тогда ИмяКолонкиТЗ = СтрокаСопоставленияБД.ИмяКолонкиИсточника; ЗаголовокКолонкиТЗ = СтрокаСопоставленияБД.СинонимКолонкиИсточника; Иначе ИмяКолонкиТЗ = СтрокаСопоставленияБД.ИмяКолонкиПриемника; ЗаголовокКолонкиТЗ = СтрокаСопоставленияБД.СинонимКолонкиПриемника; КонецЕсли; СтараяКолонкаТЗ = ТаблицаЗначений.Колонки.Найти(ИмяКолонкиТЗ); Если Ложь Или СтараяКолонкаТЗ <> Неопределено И ирОбщий.ЛиОписаниеТипов1ВходитВОписаниеТипов2Лкс(СтараяКолонкаТЗ.ТипЗначения, СтрокаСопоставленияБД.ОписаниеТиповПриемника) Или (Истина И Не СтрокаСопоставленияБД.Пометка И Не СтрокаСопоставленияБД.ПолеПоиска) Тогда Возврат Ложь; КонецЕсли; Если СтараяКолонкаТЗ <> Неопределено Тогда СтараяКолонкаТЗ.Имя = СтараяКолонкаТЗ.Имя + ирОбщий.СуффиксСлужебногоСвойстваЛкс(); КонецЕсли; НоваяКолонкаТЗ = ТаблицаЗначений.Колонки.Добавить(ИмяКолонкиТЗ, СтрокаСопоставленияБД.ОписаниеТиповПриемника, ЗаголовокКолонкиТЗ); Если СтараяКолонкаТЗ <> Неопределено Тогда ТаблицаЗначений.ЗагрузитьКолонку(ТаблицаЗначений.ВыгрузитьКолонку(СтараяКолонкаТЗ), НоваяКолонкаТЗ); ТаблицаЗначений.Колонки.Удалить(СтараяКолонкаТЗ); КонецЕсли; Возврат Истина; КонецФункции Функция СтруктураПозицийТД(ОбязательноЗаголовки = Ложь, СообщитьДинамическиеКоординаты = Ложь) Экспорт #Если Сервер И Не Сервер Тогда ТабличныйДокумент = Новый ТабличныйДокумент; #КонецЕсли ЧислоПроверяемыхЯчеек = 10000; Результат = Новый Структура("НомерСтрокиЗаголовков, НомерСтрокиДанных, НомерПоследнейСтрокиДанных"); Результат.НомерСтрокиЗаголовков = СтрокаЗаголовковТД; Результат.НомерСтрокиДанных = ПерваяСтрокаДанныхТД; Результат.НомерПоследнейСтрокиДанных = ПоследняяСтрокаДанныхТД; Если Не ЗначениеЗаполнено(ПерваяСтрокаДанныхТД) Тогда МаксКоличествоЗаполненыхЯчеекДанных = 0; КоличествоЗаполненыхЯчеекЗаголовков = 0; НачальнаяСтрокаАнализа = Макс(1, СтрокаЗаголовковТД); КонечнаяСтрокаАнализа = Мин(СтрокаЗаголовковТД + 10, ТабличныйДокумент.ВысотаТаблицы); ЧислоПроверяемыхСтрок = КонечнаяСтрокаАнализа - НачальнаяСтрокаАнализа + 1; Для НомерСтроки = НачальнаяСтрокаАнализа По КонечнаяСтрокаАнализа Цикл //КоличествоЯчеек = 0; КоличествоЗаполненыхЯчеек = 0; УникальныеЗначения = Новый Соответствие; КоличествоЯчеекСнизу = 0; КоличествоЗаполненыхЯчеекСнизу = 0; КоличествоСовпаденийЯчеекСнизу = 0; МожетБытьСтрокойЗаголовков = Не ЗначениеЗаполнено(СтрокаЗаголовковТД); Для НомерКолонки = 1 По Мин(Цел(ЧислоПроверяемыхЯчеек / ЧислоПроверяемыхСтрок) + 1, ТабличныйДокумент.ШиринаТаблицы) Цикл ОбластьЦ = ТабличныйДокумент.Область(НомерСтроки, НомерКолонки); //ЛиНезависимаяЯчейка = ОбластьЦ.Верх = НомерСтроки И ОбластьЦ.Лево = НомерКолонки; ОбластьСнизу = ТабличныйДокумент.Область(НомерСтроки + 1, НомерКолонки); ЛиНезависимаяЯчейкаСнизу = ОбластьСнизу.Верх = НомерСтроки + 1 И ОбластьСнизу.Лево = НомерКолонки; Если ЛиНезависимаяЯчейкаСнизу Тогда КоличествоЯчеекСнизу = КоличествоЯчеекСнизу + 1; ТекстЯчейкиСнизу = ОбластьСнизу.Текст; Если ЗначениеЗаполнено(ТекстЯчейкиСнизу) Тогда КоличествоЗаполненыхЯчеекСнизу = КоличествоЗаполненыхЯчеекСнизу + 1; КонецЕсли; КонецЕсли; //Если ЛиНезависимаяЯчейка Тогда // //КоличествоЯчеек = КоличествоЯчеек + 1; ТекстЯчейки = ОбластьЦ.Текст; Если ЗначениеЗаполнено(ТекстЯчейки) Тогда КоличествоЗаполненыхЯчеек = КоличествоЗаполненыхЯчеек + 1; УникальныеЗначения[Лев(ТекстЯчейки, 50)] = 1; // Обрезаем для ускорения КонецЕсли; Если Истина //И ЛиНезависимаяЯчейкаСнизу И ЗначениеЗаполнено(ТекстЯчейки) И ТекстЯчейки = ТекстЯчейкиСнизу Тогда КоличествоСовпаденийЯчеекСнизу = КоличествоСовпаденийЯчеекСнизу + 1; КонецЕсли; //КонецЕсли; //Если Истина // И Не ЛиНезависимаяЯчейка // И ЛиНезависимаяЯчейкаСнизу // И ЗначениеЗаполнено(ТекстЯчейкиСнизу) //Тогда // МожетБытьСтрокойЗаголовков = Ложь; //КонецЕсли; КонецЦикла; Если НомерСтроки = Результат.НомерСтрокиЗаголовков Тогда КоличествоЗаполненыхЯчеекЗаголовков = УникальныеЗначения.Количество(); ИначеЕсли Истина И МожетБытьСтрокойЗаголовков И КоличествоЗаполненыхЯчеекЗаголовков < УникальныеЗначения.Количество() Тогда Результат.НомерСтрокиЗаголовков = НомерСтроки; КоличествоЗаполненыхЯчеекЗаголовков = УникальныеЗначения.Количество(); Если Результат.НомерСтрокиЗаголовков >= Результат.НомерСтрокиДанных Тогда Результат.НомерСтрокиДанных = Результат.НомерСтрокиЗаголовков + 1; МаксКоличествоЗаполненыхЯчеекДанных = 0; КонецЕсли; КонецЕсли; Если КоличествоЗаполненыхЯчеекСнизу > МаксКоличествоЗаполненыхЯчеекДанных Тогда Если КоличествоСовпаденийЯчеекСнизу = 0 Тогда Если КоличествоЗаполненыхЯчеекЗаголовков <= КоличествоЯчеекСнизу Тогда Результат.НомерСтрокиДанных = НомерСтроки + 1; МаксКоличествоЗаполненыхЯчеекДанных = КоличествоЗаполненыхЯчеекСнизу; КонецЕсли; ИначеЕсли Ложь Или МаксКоличествоЗаполненыхЯчеекДанных = 0 Или КоличествоЗаполненыхЯчеек / МаксКоличествоЗаполненыхЯчеекДанных >= 2 Тогда Если КоличествоЗаполненыхЯчеекЗаголовков <= КоличествоЯчеекСнизу Тогда Результат.НомерСтрокиДанных = НомерСтроки; КонецЕсли; КонецЕсли; ИначеЕсли Истина И Не ЗначениеЗаполнено(Результат.НомерСтрокиЗаголовков) И КоличествоЗаполненыхЯчеекСнизу <= КоличествоЗаполненыхЯчеек Тогда Если КоличествоЗаполненыхЯчеекЗаголовков <= КоличествоЯчеекСнизу Тогда Результат.НомерСтрокиДанных = НомерСтроки + 1; КонецЕсли; КонецЕсли; КонецЦикла; КонецЕсли; Если Не ЗначениеЗаполнено(ПоследняяСтрокаДанныхТД) Тогда Результат.НомерПоследнейСтрокиДанных = ТабличныйДокумент.ВысотаТаблицы; МинимальноеКоличествоНепустых = 1; НачальнаяСтрокаАнализа = Результат.НомерСтрокиДанных; КонечнаяСтрокаАнализа = ТабличныйДокумент.ВысотаТаблицы; ЧислоПроверяемыхСтрок = КонечнаяСтрокаАнализа - НачальнаяСтрокаАнализа + 1; Если ЧислоПроверяемыхСтрок > ЧислоПроверяемыхЯчеек Тогда Если СообщитьДинамическиеКоординаты Тогда ирОбщий.СообщитьЛкс("Автоподбор конечной строки данных табличного документа не выполнен из-за слишком большого числа строк в нем"); КонецЕсли; Иначе Для НомерСтроки = НачальнаяСтрокаАнализа По КонечнаяСтрокаАнализа Цикл КоличествоЯчеекЗаполнено = 0; Для НомерКолонки = 1 По Мин(Цел(ЧислоПроверяемыхЯчеек / ЧислоПроверяемыхСтрок) + 1, ТабличныйДокумент.ШиринаТаблицы) Цикл Если ЗначениеЗаполнено(ТабличныйДокумент.Область(НомерСтроки, НомерКолонки).Текст) Тогда КоличествоЯчеекЗаполнено = КоличествоЯчеекЗаполнено + 1; Если КоличествоЯчеекЗаполнено >= МинимальноеКоличествоНепустых Тогда Прервать; КонецЕсли; КонецЕсли; КонецЦикла; Если КоличествоЯчеекЗаполнено < МинимальноеКоличествоНепустых Тогда Результат.НомерПоследнейСтрокиДанных = Макс(Результат.НомерСтрокиДанных, НомерСтроки - 1); Прервать; КонецЕсли; КонецЦикла; Если СообщитьДинамическиеКоординаты Тогда ирОбщий.СообщитьЛкс("Автоподбором найдено заголовки на строке №" + Результат.НомерСтрокиЗаголовков + " и данные в строках [" + Результат.НомерСтрокиДанных + ";" + Результат.НомерПоследнейСтрокиДанных + "]"); КонецЕсли; КонецЕсли; КонецЕсли; Если ОбязательноЗаголовки И Не ЗначениеЗаполнено(Результат.НомерСтрокиЗаголовков) Тогда Результат.НомерСтрокиЗаголовков = 1; Если Результат.НомерСтрокиДанных <= 1 Тогда Результат.НомерСтрокиДанных = 2; ТабличныйДокумент.ВставитьОбласть(ТабличныйДокумент.Область(1,1), ТабличныйДокумент.Область(1,1), ТипСмещенияТабличногоДокумента.ПоВертикали, Ложь); ТабличныйДокумент.Область(1,1).Текст = ""; КонецЕсли; КонецЕсли; Если СообщитьДинамическиеКоординаты И Не ЗначениеЗаполнено(Результат.НомерСтрокиЗаголовков) Тогда ирОбщий.СообщитьЛкс("Не указан номер строки заголовков и отключен ее автоподбор. Будут использованы сгенерированные заголовки колонок."); КонецЕсли; Возврат Результат; КонецФункции Функция ПолучитьКолонкиТабличногоДокумента(СтруктураПозицийТД = Неопределено, ТолькоВыделенныеСтрокиТД = Ложь) Экспорт СтруктураПозицийТД = Неопределено; КолонкиТабличногоДокумента = Новый Соответствие; мПлатформа = ирКэш.Получить(); #Если Сервер И Не Сервер Тогда мПлатформа = Обработки.ирПлатформа.Создать(); ТабличныйДокумент = Новый ТабличныйДокумент; #КонецЕсли Если СтруктураПозицийТД = Неопределено Тогда СтруктураПозицийТД = СтруктураПозицийТД(); КонецЕсли; НомерСтрокиПримера = СтруктураПозицийТД.НомерСтрокиДанных; Если ТабличныйДокумент.ТекущаяОбласть.Верх <= СтруктураПозицийТД.НомерПоследнейСтрокиДанных Тогда НомерСтрокиПримера = Макс(НомерСтрокиПримера, ТабличныйДокумент.ТекущаяОбласть.Верх); КонецЕсли; Для Счетчик = 1 По ТабличныйДокумент.ШиринаТаблицы Цикл СтрокаНомераКолонки = ИмяКолонкиТабличногоДокумента(Счетчик); СинонимКолонки = ""; Если ЗначениеЗаполнено(СтруктураПозицийТД.НомерСтрокиЗаголовков) Тогда СинонимКолонки = СокрЛП(ТабличныйДокумент.Область(СтруктураПозицийТД.НомерСтрокиЗаголовков, Счетчик).Текст); КонецЕсли; Если Не ЗначениеЗаполнено(СинонимКолонки) Тогда СинонимКолонки = "Колонка " + СтрокаНомераКолонки; КонецЕсли; ИмяКолонки = СтрокаНомераКолонки; ПримерДанных = ТабличныйДокумент.Область(НомерСтрокиПримера, Счетчик).Текст; КолонкиТабличногоДокумента[ИмяКолонки] = Новый Структура("Имя, Заголовок, ПримерДанных", ИмяКолонки, СинонимКолонки, ПримерДанных); КонецЦикла; Возврат КолонкиТабличногоДокумента; КонецФункции Функция ИмяКолонкиТабличногоДокумента(Знач НомерКолонки) СтрокаНомераКолонки = Формат(НомерКолонки, "ЧЦ=3; ЧВН="); Возврат СтрокаНомераКолонки; КонецФункции Процедура СообщитьИтогиКонвертации(Знач КоличествоОшибокКонвертации) Если КоличествоОшибокКонвертации Тогда ирОбщий.СообщитьЛкс("Помечено ячеек, содержащих ошибки/неоднозначности: " + КоличествоОшибокКонвертации, СтатусСообщения.Внимание); Иначе ирОбщий.СообщитьЛкс("Не выявлено ячеек, содержащих ошибки"); КонецЕсли; КонецПроцедуры Функция ЗагрузитьВБДИзТаблицыЗначений(Параметры) Экспорт ЭтотОбъект.ВыполнятьЗагрузкуНаСервере = Параметры.ВыполнятьНаСервере; ТаблицаИсточник = Параметры.ТаблицаЗначенийОтобранное; Записывать = Параметры.Записывать; ЗаписыватьОбъект = Истина; КоличествоЭлементов = ТаблицаИсточник.Количество(); Если КоличествоЭлементов <= 0 Тогда ирОбщий.СообщитьЛкс("В источнике (таблице значений) нет строк"); Возврат Неопределено; КонецЕсли; ТекстВопросаИсточника = " строк в таблице БД " + ПолноеИмяТаблицы; мКоличествоУспешно = 0; мКоличествоНеуспешно = 0; ОбновитьКоличествоУспешноДляОтображения(); ОбновитьКолонкиТаблицыБД(, Записывать); ТипТаблицыБД = ирОбщий.ТипТаблицыБДЛкс(ПолноеИмяТаблицы); // Поиск строк БД Запрос = Неопределено; СтруктураКлючаСтроки = ирОбщий.СтруктураКлючаТаблицыБДЛкс(ПолноеИмяТаблицы, Истина); СтрокаКлючаСтрокиБД = ""; Для Каждого КлючИЗначение Из СтруктураКлючаСтроки Цикл Если СтрокаКлючаСтрокиБД <> "" Тогда СтрокаКлючаСтрокиБД = СтрокаКлючаСтрокиБД + ", "; КонецЕсли; СтрокаКлючаСтрокиБД = СтрокаКлючаСтрокиБД + "Т." + КлючИЗначение.Ключ; КонецЦикла; ПоляПоиска = СопоставлениеКолонокБД.НайтиСтроки(Новый Структура("ПолеПоиска", Истина)); Если ПоляПоиска.Количество() > 0 Тогда ТекстЗапроса = "ВЫБРАТЬ Первые 2 |" + СтрокаКлючаСтрокиБД + " |ИЗ " + ирКэш.ИмяТаблицыИзМетаданныхЛкс(ПолноеИмяТаблицы) + " КАК Т |ГДЕ ИСТИНА"; Для каждого СтрокаПоиска Из ПоляПоиска Цикл ВыражениеПоляПоиска = "Т." + СтрокаПоиска.ИмяКолонкиПриемника; ВыражениеПараметра = "&" + СтрокаПоиска.ИмяКолонкиПриемника; Если ирОбщий.ЛиОписаниеТиповНеограниченнойСтрокиЛкс(СтрокаПоиска.ОписаниеТиповПриемника) Тогда ВыражениеПоляПоиска = "ВЫРАЗИТЬ(" + ВыражениеПоляПоиска + " КАК СТРОКА(1024))"; ВыражениеПараметра = "ВЫРАЗИТЬ(" + ВыражениеПараметра + " КАК СТРОКА(1024))"; КонецЕсли; ТекстЗапроса = ТекстЗапроса + " | И " + ВыражениеПоляПоиска + " = " + ВыражениеПараметра + ""; КонецЦикла; Запрос = Новый Запрос(ТекстЗапроса); КонецЕсли; ПроверитьДобавитьКолонкуИдентификатораСтроки(ТаблицаИсточник); ПредставлениеПроцесса = "Поиск" + ТекстВопросаИсточника; Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(КоличествоЭлементов, ПредставлениеПроцесса); МакетныйОбъект = Неопределено; ТекущаяГруппаТипаМетаданных = Неопределено; ирОбщий.ПолучитьМакетныйОбъектДанныхТаблицыБДЛкс(ПолноеИмяТаблицы, МакетныйОбъект, ТекущаяГруппаТипаМетаданных); Если ТекущаяГруппаТипаМетаданных = "Ссылочный" Тогда МенеджерТипа = ирОбщий.ПолучитьМенеджерЛкс(ПолноеИмяТаблицы); КонецЕсли; Для Каждого СтрокаТЗ Из ТаблицаИсточник Цикл ирОбщий.ОбработатьИндикаторЛкс(Индикатор); Если Не ЗначениеЗаполнено(СтрокаТЗ[мИмяКолонкиНомерСтроки]) Тогда СтрокаТЗ[мИмяКолонкиНомерСтроки] = ТаблицаИсточник.Индекс(СтрокаТЗ) + 1; КонецЕсли; Отказ = Ложь; СтрокаТаблицыБД = ТаблицаБД.Добавить(); СтрокаТаблицыБД[мИмяКолонкиНомерСтроки] = СтрокаТЗ[мИмяКолонкиНомерСтроки]; РезультатПоиска = "Не найдено"; Для каждого СтрокаСопоставления Из СопоставлениеКолонокБД Цикл Если Не СтрокаСопоставления.Пометка И Не СтрокаСопоставления.ПолеПоиска Тогда Продолжить; КонецЕсли; Если СтрокаСопоставления.ИзИсточника Тогда НовоеЗначение = СтрокаТЗ[СтрокаСопоставления.ИмяКолонкиИсточника]; Иначе НовоеЗначение = СтрокаСопоставления.Значение; КонецЕсли; СтрокаТаблицыБД[СтрокаСопоставления.ИмяКолонкиПриемника] = НовоеЗначение; КонецЦикла; Если Запрос <> Неопределено Тогда СтрокаОшибок = ""; Для каждого СтрокаПоиска Из ПоляПоиска Цикл Запрос.УстановитьПараметр(СтрокаПоиска.ИмяКолонкиПриемника, СтрокаТаблицыБД[СтрокаПоиска.ИмяКолонкиПриемника]); КонецЦикла; Если Не ПустаяСтрока(СтрокаОшибок) Тогда СтрокаТаблицыБД[мИмяКолонкиРезультатПоиска] = "Не указаны значения полей поиска: " + СтрокаОшибок; Продолжить; КонецЕсли; Выборка = Запрос.Выполнить().Выбрать(); Если Выборка.Следующий() Тогда Если Выборка.Количество() > 1 Тогда РезультатПоиска = "Найдено > 1"; Иначе РезультатПоиска = "Найдено 1"; КонецЕсли; ЗаполнитьЗначенияСвойств(СтрокаТаблицыБД, Выборка); КонецЕсли; КонецЕсли; СтрокаНайдена = Найти(РезультатПоиска, "Найдено") = 1; Если Не СтрокаНайдена Тогда Если ТекущаяГруппаТипаМетаданных = "ВложеннаяТаблица" Тогда Если Не ЗначениеЗаполнено(СтрокаТаблицыБД.Ссылка) Тогда РезультатПоиска = "Не указано значение ссылки объекта-владельца вложенной таблицы"; КонецЕсли; ИначеЕсли ТекущаяГруппаТипаМетаданных = "Ссылочный" Тогда СтрокаТаблицыБД.Ссылка = МенеджерТипа.ПолучитьСсылку(); КонецЕсли; КонецЕсли; СтрокаТаблицыБД[мИмяКолонкиРезультатПоиска] = РезультатПоиска; КонецЦикла; ирОбщий.ОсвободитьИндикаторПроцессаЛкс(); Если СвязиИПараметрыВыбора Тогда КолонкиСПроверками = ирОбщий.КолонкиТаблицыБДСПроверкамиЛкс(ПолноеИмяТаблицы); КолонкиСНарушениями = Новый Структура; Если Не ирОбщий.ПроверитьТаблицуЗначенийНаСогласованностьЛкс(ТаблицаБД, КолонкиСПроверками, КолонкиСНарушениями,,,, ирОбщий.ЛиТипВложеннойТаблицыБДЛкс(ТипТаблицыБД)) Тогда Возврат Неопределено; КонецЕсли; КонецЕсли; Если Записывать Тогда #Если Сервер И Не Сервер Тогда ЗагрузитьРезультатОбработкиОбъекта(); ОбработатьЭлементыОбъекта(); #КонецЕсли СтруктураПотоков = ирОбщий.НоваяСтруктураМногопоточнойОбработкиЛкс("ОбработатьЭлементыОбъекта", ЭтотОбъект, "ЗагрузитьРезультатОбработкиОбъекта", КоличествоОбъектовВПорции, КоличествоПотоков); // Установка значений реквизитов и запись в БД СтруктураКлючаОбъекта = ирОбщий.СтруктураКлючаТаблицыБДЛкс(ПолноеИмяТаблицы, Ложь); Если ТекущаяГруппаТипаМетаданных = "Ссылочный" Тогда СтруктураКлючаОбъекта.Вставить(мИмяКолонкиРезультатПоиска); // Опасно КонецЕсли; СтрокаКлючаОбъектаБД = ""; Для Каждого КлючИЗначение Из СтруктураКлючаОбъекта Цикл Если СтрокаКлючаОбъектаБД <> "" Тогда СтрокаКлючаОбъектаБД = СтрокаКлючаОбъектаБД + ", "; КонецЕсли; СтрокаКлючаОбъектаБД = СтрокаКлючаОбъектаБД + КлючИЗначение.Ключ; КонецЦикла; ТаблицаКлючейОбъектовБД = ТаблицаБД.Скопировать(, СтрокаКлючаОбъектаБД); ТаблицаКлючейОбъектовБД.Свернуть(СтрокаКлючаОбъектаБД); ирОбщий.ДобавитьИндексВТаблицуЛкс(ТаблицаИсточник, мИмяКолонкиНомерСтроки); ПредставлениеПроцесса = "Загрузка" + ТекстВопросаИсточника; ирОбщий.СообщитьЛкс("Всего: " + КоличествоЭлементов, СтатусСообщения.Информация); Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(КоличествоЭлементов, ПредставлениеПроцесса); Для Каждого КлючОбъектаБД Из ТаблицаКлючейОбъектовБД Цикл Если ирОбщий.ОбработатьИндикаторЛкс(Индикатор) Тогда ОбновитьКоличествоУспешноДляОтображения(); КонецЕсли; ОбъектБД = Неопределено; ЗаполнитьЗначенияСвойств(СтруктураКлючаОбъекта, КлючОбъектаБД); СтрокиОбъекта = ТаблицаБД.НайтиСтроки(СтруктураКлючаОбъекта); КопияСтрокОбъекта = ТаблицаБД.Скопировать(СтрокиОбъекта); Если Истина И ТекущаяГруппаТипаМетаданных = "ВложеннаяТаблица" И Не ЗначениеЗаполнено(КлючОбъектаБД.Ссылка) Тогда КоличествоНеуспешно = КоличествоНеуспешно + КопияСтрокОбъекта.Количество(); Продолжить; КонецЕсли; СтрокиТЗ = Новый Массив; Для Каждого СтрокаОбъекта Из СтрокиОбъекта Цикл СтрокаТЗ = ТаблицаИсточник.Найти(СтрокаОбъекта[мИмяКолонкиНомерСтроки], мИмяКолонкиНомерСтроки); СтрокиТЗ.Добавить(СтрокаТЗ); КонецЦикла; КопияСтрокТЗ = ТаблицаИсточник.Скопировать(СтрокиТЗ); ДобавитьОбъектВОчередьОбработки(ирОбщий.СтруктураИзСтрокиТаблицыИлиДереваИлиВыборкиЛкс(КлючОбъектаБД), СтруктураКлючаСтроки, ПолноеИмяТаблицы, КопияСтрокОбъекта, КопияСтрокТЗ, СобытияОбработкиОбъектов, СтрокиОбъекта, СтруктураПотоков, КолонкиСНарушениями); КонецЦикла; ирОбщий.ОжидатьЗавершенияВсехПотоковОбработкиЛкс(СтруктураПотоков); ирОбщий.ОсвободитьИндикаторПроцессаЛкс(, Истина); ОбновитьКоличествоУспешноДляОтображения(); ирОбщий.СообщитьЛкс("Загружено строк " + КоличествоУспешно + " из " + КоличествоЭлементов + ".", СтатусСообщения.Информация); КонецЕсли; РеквизитыДляРезультата = "ТаблицаБД, КоличествоУспешно, КоличествоНеуспешно"; Результат = Новый Структура(РеквизитыДляРезультата); ЗаполнитьЗначенияСвойств(Результат, ЭтотОбъект, РеквизитыДляРезультата); Возврат Результат; КонецФункции Процедура ДобавитьОбъектВОчередьОбработки(КлючОбъектаБД, СтруктураКлючаСтроки, ПолноеИмяТаблицы, КопияСтрокОбъекта, КопияСтрокТЗ, СобытияОбработкиОбъектов, СтрокиРезультатовОбъекта = Неопределено, СтруктураПотоков, КолонкиСНарушениями) ПараметрыОбработкиОбъекта = Новый Структура; ПараметрыОбработкиОбъекта.Вставить("КлючОбъектаБД", КлючОбъектаБД); ПараметрыОбработкиОбъекта.Вставить("ПолноеИмяТаблицы", ПолноеИмяТаблицы); ПараметрыОбработкиОбъекта.Вставить("СтруктураКлючаСтроки", СтруктураКлючаСтроки); ПараметрыОбработкиОбъекта.Вставить("КопияСтрокОбъекта", КопияСтрокОбъекта); ПараметрыОбработкиОбъекта.Вставить("КопияСтрокТЗ", КопияСтрокТЗ); ПараметрыОбработкиОбъекта.Вставить("СобытияОбработкиОбъектов", СобытияОбработкиОбъектов); ПараметрыОбработкиОбъекта.Вставить("СопоставлениеКолонокБД", СопоставлениеКолонокБД); ПараметрыОбработкиОбъекта.Вставить("КолонкиСНарушениями", КолонкиСНарушениями); ирОбщий.ДобавитьОбъектВОчередьМногопоточнойОбработкиЛкс(СтруктураПотоков, ПараметрыОбработкиОбъекта, СтрокиРезультатовОбъекта); КонецПроцедуры // Обработать элементы объекта // // Параметры: // ПараметрыОбработкиОбъекта - Структура - // // Возвращаемое значение: // - // Функция ОбработатьЭлементыОбъекта(ПараметрыОбработкиОбъекта) Экспорт #Если Сервер И Не Сервер Тогда ПараметрыОбработкиОбъекта = Новый Структура; #КонецЕсли КлючОбъектаБД = ПараметрыОбработкиОбъекта.КлючОбъектаБД; СтруктураКлючаСтроки = ПараметрыОбработкиОбъекта.СтруктураКлючаСтроки; ПолноеИмяТаблицы = ПараметрыОбработкиОбъекта.ПолноеИмяТаблицы; СтрокиОбъекта = ПараметрыОбработкиОбъекта.КопияСтрокОбъекта; КопияСтрокТЗ = ПараметрыОбработкиОбъекта.КопияСтрокТЗ; СобытияОбработкиОбъектов = ПараметрыОбработкиОбъекта.СобытияОбработкиОбъектов; СопоставлениеКолонокБД = ПараметрыОбработкиОбъекта.СопоставлениеКолонокБД; КолонкиСНарушениями = ПараметрыОбработкиОбъекта.КолонкиСНарушениями; #Если Сервер И Не Сервер Тогда СтрокиОбъекта = Новый ТаблицаЗначений; КопияСтрокТЗ = Новый ТаблицаЗначений; #КонецЕсли ирОбщий.ДобавитьИндексВТаблицуЛкс(КопияСтрокТЗ, мИмяКолонкиНомерСтроки); МакетныйОбъект = Неопределено; ТекущаяГруппаТипаМетаданных = Неопределено; ирОбщий.ПолучитьМакетныйОбъектДанныхТаблицыБДЛкс(ПолноеИмяТаблицы, МакетныйОбъект, ТекущаяГруппаТипаМетаданных); МетаданныеИсточника = МетаданныеТаблицыБД(); ИмяПоляСсылка = ""; СтрокаОбъекта = СтрокиОбъекта[0]; Если ТекущаяГруппаТипаМетаданных = "ВложеннаяТаблица" Тогда Фрагменты = ирОбщий.СтрРазделитьЛкс(ПолноеИмяТаблицы); ИмяТабличнойЧасти = Фрагменты[2]; Фрагменты.Удалить(2); ПолноеИмяТаблицыВладельца = ирОбщий.СтрСоединитьЛкс(Фрагменты, "."); ОбъектБД = ирОбщий.ОбъектБДПоКлючуЛкс(ПолноеИмяТаблицыВладельца, СтрокаОбъекта.Ссылка); ТабличнаяЧасть = ОбъектБД.Данные[ИмяТабличнойЧасти]; ИначеЕсли ТекущаяГруппаТипаМетаданных <> "Ссылочный" Или Найти(КлючОбъектаБД[мИмяКолонкиРезультатПоиска], "Найдено") = 1 Тогда ОбъектБД = ирОбщий.ОбъектДанныхИзСтрокиРезультатаЗапросаЛкс(КлючОбъектаБД, МакетныйОбъект, ТекущаяГруппаТипаМетаданных, Истина); Иначе// Если ТекущаяГруппаТипаМетаданных = "Ссылочный" И Не СтрокаНайдена Тогда Если ЗначениеЗаполнено(СтрокаОбъекта.Ссылка) Тогда // Лишние обращения к БД ОбъектБД = ирОбщий.ОбъектБДПоКлючуЛкс(МетаданныеИсточника.ПолноеИмя(), СтрокаОбъекта.Ссылка); КонецЕсли; Если ОбъектБД.Методы.ЭтоНовый() Тогда ЭтоГруппаДляНового = Ложь; Если ирОбщий.ЛиМетаданныеОбъектаСГруппамиЛкс(МетаданныеИсточника) Тогда СтрокаСопоставленияЭтоГруппа = СопоставлениеКолонокБД.Найти("ЭтоГруппа", "ИмяКолонкиПриемника"); Если СтрокаСопоставленияЭтоГруппа.Пометка Или СтрокаСопоставленияЭтоГруппа.ПолеПоиска Тогда ЭтоГруппаДляНового = СтрокаОбъекта.ЭтоГруппа; КонецЕсли; КонецЕсли; ОбъектБД = ирОбщий.ОбъектБДПоКлючуЛкс(МетаданныеИсточника.ПолноеИмя(), ЭтоГруппаДляНового, Истина,,, ирОбщий.ИдентификаторСсылкиЛкс(СтрокаОбъекта.Ссылка)); КонецЕсли; КонецЕсли; #Если Не Клиент Тогда ПолучитьСообщенияПользователю(Истина); СообщенияОбработки = Новый ЗаписьXML; СообщенияОбработки.УстановитьСтроку(""); #КонецЕсли ОтказОбъекта = Ложь; ОписаниеОшибки = ""; УспехОбработчика = ирОбщий.ОбработатьСобытиеЛкс(СобытияОбработкиОбъектов, Метаданные().Макеты.АлгоритмПередОбработкойОбъекта.Имя, ОписаниеОшибки,, ОбъектБД.Данные, ОбъектБД.Методы, ОтказОбъекта); Если Не УспехОбработчика Тогда ОтказОбъекта = Истина; КонецЕсли; КоличествоУспешныхСтрокОбъекта = 0; Для Каждого СтрокаОбъекта Из СтрокиОбъекта Цикл Если ОтказОбъекта Тогда СтрокаОбъекта[мИмяКолонкиРезультатЗаписи] = "Отказ в событии ПередОбработкойОбъекта: " + ОписаниеОшибки; КоличествоНеуспешно = КоличествоНеуспешно + 1; Продолжить; КонецЕсли; ОтказСтроки = Ложь; СтрокаНайдена = Найти(СтрокаОбъекта[мИмяКолонкиРезультатПоиска], "Найдено") = 1; Если Ложь Или (СтрокаНайдена И Не ОбновлятьСтрокиБД) Или (Не СтрокаНайдена И Не ДобавлятьСтрокиБД) Тогда //Для каждого СтрокаСопоставления Из ПоляПоиска Цикл // СтрокаТаблицыБД[СтрокаСопоставления.ИмяКолонкиПриемника] = СтрокаТаблицыБД[СтрокаСопоставления.ИмяКолонкиИсточника]; //КонецЦикла; Если СтрокаНайдена Тогда СтрокаОбъекта[мИмяКолонкиРезультатЗаписи] = "Не разрешено обновлять строки"; Иначе СтрокаОбъекта[мИмяКолонкиРезультатЗаписи] = "Не разрешено добавлять строки"; КонецЕсли; КоличествоНеуспешно = КоличествоНеуспешно + 1; Продолжить; КонецЕсли; Если СтрокаНайдена Тогда Если ТекущаяГруппаТипаМетаданных = "Ссылочный" Тогда СтрокаОбъектаБД = ОбъектБД.Данные; ИначеЕсли ТекущаяГруппаТипаМетаданных = "Регистр" Тогда Если СтруктураКлючаСтроки.Свойство("НомерСтроки") Тогда СтрокаОбъектаБД = ОбъектБД.Данные[СтрокаОбъекта.НомерСтроки - 1]; Иначе СтрокаОбъектаБД = ОбъектБД.Данные[0]; КонецЕсли; ИначеЕсли ТекущаяГруппаТипаМетаданных = "ВложеннаяТаблица" Тогда СтрокаОбъектаБД = ТабличнаяЧасть[СтрокаОбъекта.НомерСтроки - 1]; Иначе СтрокаОбъектаБД = ОбъектБД.Данные; КонецЕсли; Иначе Если ТекущаяГруппаТипаМетаданных = "ВложеннаяТаблица" Тогда СтрокаОбъектаБД = ТабличнаяЧасть.Добавить(); Если ирОбщий.ЛиТипИмитатораОбъектаЛкс(ТипЗнч(ОбъектБД.Методы)) Тогда СтрокаОбъектаБД.НомерСтроки = ТабличнаяЧасть.Количество(); КонецЕсли; СтрокаОбъекта.НомерСтроки = СтрокаОбъектаБД.НомерСтроки; ИначеЕсли ТекущаяГруппаТипаМетаданных = "Регистр" Тогда СтрокаОбъектаБД = ОбъектБД.Данные.Добавить(); Если СтруктураКлючаСтроки.Свойство("НомерСтроки") Тогда Если ирОбщий.ЛиТипИмитатораОбъектаЛкс(ТипЗнч(ОбъектБД.Методы)) Тогда СтрокаОбъектаБД.НомерСтроки = ОбъектБД.Данные.Количество(); КонецЕсли; СтрокаОбъекта.НомерСтроки = СтрокаОбъектаБД.НомерСтроки; КонецЕсли; Иначе СтрокаОбъектаБД = ОбъектБД.Данные; КонецЕсли; КонецЕсли; ОписаниеОшибки = ""; КопияСтрокиТЗ = КопияСтрокТЗ.Найти(СтрокаОбъекта[мИмяКолонкиНомерСтроки], мИмяКолонкиНомерСтроки); УспехОбработчика = ирОбщий.ОбработатьСобытиеЛкс(СобытияОбработкиОбъектов, Метаданные().Макеты.АлгоритмПередЗагрузкойСтроки.Имя, ОписаниеОшибки,, ОбъектБД.Данные, ОбъектБД.Методы, СтрокаОбъектаБД, КопияСтрокиТЗ, СтрокаНайдена, ОтказСтроки, СтрокаОбъекта); Если Не УспехОбработчика Тогда ОтказСтроки = Истина; КонецЕсли; Если Не ОтказСтроки Тогда Для каждого СтрокаСопоставления Из СопоставлениеКолонокБД Цикл Если Ложь Или Не СтрокаСопоставления.ДоступноИзменение Или (Истина И Не СтрокаСопоставления.Пометка И Не СтрокаСопоставления.ПолеПоиска) Или (Истина И СтрокаСопоставления.Принадлежность = "" + Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляГруппы И Не ОбъектБД.Данные.ЭтоГруппа) Или (Истина И СтрокаСопоставления.Принадлежность = "" + Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляЭлемента И ОбъектБД.Данные.ЭтоГруппа) Тогда Продолжить; КонецЕсли; Если Ложь //Или Не СтрокаНайдена Или СтрокаСопоставления.Пометка Или СтрокаСопоставления.ПолеПоиска Тогда ИмяКолонки = СтрокаСопоставления.ИмяКолонкиПриемника; НовоеЗначение = СтрокаОбъекта[ИмяКолонки]; Если КолонкиСНарушениями <> Неопределено И КолонкиСНарушениями.Свойство(ИмяКолонки) Тогда Если СтрокаОбъекта["Несогласовано_" + ИмяКолонки] Тогда Продолжить; КонецЕсли; КонецЕсли; Если Истина И СтрокаСопоставления.НеОчищать И СтрокаСопоставления.ИзИсточника И Не СтрокаСопоставления.ПолеПоиска И ТипЗнч(НовоеЗначение) <> Тип("Булево") И Не ЗначениеЗаполнено(НовоеЗначение) Тогда Продолжить; КонецЕсли; Если Истина И СтрокаСопоставления.ТолькоДляНовых И СтрокаНайдена И Не СтрокаСопоставления.ПолеПоиска Тогда Продолжить; КонецЕсли; Попытка Если ЗначениеЗаполнено(СтрокаСопоставления.ДопРеквизит) Тогда ирОбщий.УстановитьЗначениеДопРеквизитаБСПЛкс(СтрокаОбъектаБД, СтрокаСопоставления.ДопРеквизит, НовоеЗначение, ИмяПоляСсылка, Истина, Ложь); Иначе СтрокаОбъектаБД[СтрокаСопоставления.ИмяКолонкиПриемника] = НовоеЗначение; КонецЕсли; Исключение ОписаниеОшибки = "Ошибка при установке значения реквизита """ + СтрокаСопоставления.ИмяКолонкиПриемника + """: " + ОписаниеОшибки(); Если ВыводитьОшибкаЗагрузкиСразу Тогда ирОбщий.СообщитьЛкс(ОписаниеОшибки, СтатусСообщения.Внимание); КонецЕсли; ОтказСтроки = Истина; Прервать; КонецПопытки; КонецЕсли; КонецЦикла; КонецЕсли; Если Не ОтказСтроки Тогда ОписаниеОшибки = ""; УспехОбработчика = ирОбщий.ОбработатьСобытиеЛкс(СобытияОбработкиОбъектов, Метаданные().Макеты.АлгоритмПослеЗагрузкиСтроки.Имя, ОписаниеОшибки,, ОбъектБД.Данные, ОбъектБД.Методы, СтрокаОбъектаБД, КопияСтрокиТЗ, СтрокаНайдена, ОтказСтроки); Если Не УспехОбработчика Тогда ОтказСтроки = Истина; КонецЕсли; КонецЕсли; //ЗаполнитьЗначенияСвойств(СтрокаТаблицыБД, СтрокаОбъектаБД,, СтрокаКлючаОбъектаБД); Если ОтказСтроки Тогда ОписаниеОшибки = "Загрузка строки отменена: " + ОписаниеОшибки; СтрокаОбъекта[мИмяКолонкиРезультатЗаписи] = ОписаниеОшибки; Иначе СтрокаОбъекта[мИмяКолонкиРезультатЗаписи] = "Обработана"; КоличествоУспешныхСтрокОбъекта = КоличествоУспешныхСтрокОбъекта + 1; КонецЕсли; КонецЦикла; ОписаниеОшибки = ""; //Если Записывать Тогда Если Не ОтказОбъекта И КоличествоУспешныхСтрокОбъекта > 0 Тогда ЗаписатьОбъект(ОбъектБД, ОписаниеОшибки, СтрокиОбъекта); Если ВыводитьОшибкаЗагрузкиСразу И ЗначениеЗаполнено(ОписаниеОшибки) Тогда ирОбщий.СообщитьЛкс(ОписаниеОшибки, СтатусСообщения.Внимание); КонецЕсли; КонецЕсли; //КонецЕсли; ТекстСообщений = ""; #Если Не Клиент Тогда СообщенияОбъекта = ПолучитьСообщенияПользователю(Истина); ТекстСообщений = ирОбщий.СоединитьСообщенияПользователюЛкс(СообщенияОбъекта); #КонецЕсли СтрокиОбъекта[0][мИмяКолонкиСообщенияОбработки] = ТекстСообщений; СтрокиРезультатов = СтрокиОбъекта.Скопировать(, мИмяКолонкиНомерСтроки + "," + мИмяКолонкиРезультатЗаписи + "," + мИмяКолонкиСообщенияОбработки); РезультатОбработки = Новый Структура("СтрокиРезультатов, ОшибкаЗаписи", СтрокиРезультатов, ОписаниеОшибки); Возврат РезультатОбработки; КонецФункции Процедура ЗагрузитьРезультатОбработкиОбъекта(Знач Результат, Знач СтрокиТаблицыБД) Экспорт СтрокиРезультатов = Результат.СтрокиРезультатов; #Если Сервер И Не Сервер Тогда СтрокиТаблицыБД = Новый ТаблицаЗначений; СтрокиРезультатов = Новый ТаблицаЗначений; #КонецЕсли ОшибкаЗаписи = Результат.ОшибкаЗаписи; ирОбщий.ДобавитьИндексВТаблицуЛкс(СтрокиРезультатов, мИмяКолонкиНомерСтроки); Для Каждого СтрокаТаблицыБД Из СтрокиТаблицыБД Цикл СтрокаРезультата = СтрокиРезультатов.Найти(СтрокаТаблицыБД[мИмяКолонкиНомерСтроки], мИмяКолонкиНомерСтроки); ЗаполнитьЗначенияСвойств(СтрокаТаблицыБД, СтрокаРезультата); Если СтрокаТаблицыБД[мИмяКолонкиРезультатЗаписи] = "Обработана" Тогда Если ЗначениеЗаполнено(ОшибкаЗаписи) Тогда СтрокаТаблицыБД[мИмяКолонкиРезультатЗаписи] = "Ошибка записи: " + ОшибкаЗаписи; мКоличествоНеуспешно = мКоличествоНеуспешно + 1; Иначе СтрокаТаблицыБД[мИмяКолонкиРезультатЗаписи] = "Успех"; мКоличествоУспешно = мКоличествоУспешно + 1; КонецЕсли; Иначе мКоличествоНеуспешно = мКоличествоНеуспешно + 1; КонецЕсли; КонецЦикла; КонецПроцедуры Процедура ОбновитьКоличествоУспешноДляОтображения() ЭтотОбъект.КоличествоУспешно = мКоличествоУспешно; ЭтотОбъект.КоличествоНеуспешно = мКоличествоНеуспешно; КонецПроцедуры Функция ОбработатьСобытиеЛкс(ТаблицаСобытий, ИмяСобытия, выхОписаниеОшибки, П1 = null, П2 = null, П3 = null, П4 = null, П5 = null, П6 = null, П7 = null, П8 = null) Экспорт Алгоритм = СобытияОбработкиОбъектов.Найти(ИмяСобытия).Алгоритм; Попытка Выполнить(Алгоритм); Исключение выхОписаниеОшибки = ПолучитьПричинуОшибки(ОписаниеОшибки()); Возврат Ложь; КонецПопытки; Возврат Истина; КонецФункции // Функция выполняет контроль заполнения строки данных табличного документа // сообщает об ошибках и устанавливает коментарии к ошибочным ячейкам // // Параметры: // ТабличныйДокумент - ТабличныйДокумент, у которого необходимо сформировать шапку // НомерСтроки - Число, номер строки табличного документа // ТекстыЯчеек - возвращает массив текстов ячеек строки, // // Возвращаемое значение: // структура, ключ - Имя загружаемого реквизита, Значение - Значение загружаемого реквизита // Функция КонвертироватьСтрокуТД(ТабличныйДокумент, НомерСтроки, ТекстыЯчеек = Неопределено, КоличествоОшибок = 0, Знач РазрешитьСозданиеОбъектов = Ложь, КэшПоиска = Неопределено) ТекстыЯчеек = Новый Массив; ТекстыЯчеек.Добавить(Неопределено); ЯчейкиСтроки = Новый Массив; ЯчейкиСтроки.Добавить(Неопределено); Для НомерКолонки = 1 По ТабличныйДокумент.ШиринаТаблицы Цикл ОбластьЯчейки = ТабличныйДокумент.Область(НомерСтроки, НомерКолонки); Если ОбластьЯчейки.Лево <> НомерКолонки Тогда // Не левая ячейка объединенной горизонтально области ЯчейкиСтроки.Добавить(Неопределено); ТекстыЯчеек.Добавить(""); Иначе ЯчейкиСтроки.Добавить(ОбластьЯчейки); ТекстыЯчеек.Добавить(СокрЛП(ОбластьЯчейки.Текст)); КонецЕсли; КонецЦикла; Если СопоставлениеКолонокТЗ.Колонки.Найти("Зависимая") = Неопределено Тогда ВызватьИсключение "Сначала нужно вызвать функцию ВычислитьЗависимостиКонвертации"; КонецЕсли; ПомеченныеКолонки = СопоставлениеКолонокТЗ.НайтиСтроки(Новый Структура("Пометка", Истина)); РезультатыЯчеек = Новый Структура; Для Этап = 1 По 2 Цикл Для каждого СтрокаСопоставления Из ПомеченныеКолонки Цикл Если Ложь Или Этап = 1 И СтрокаСопоставления.Зависимая Или Этап = 2 И Не СтрокаСопоставления.Зависимая Тогда Продолжить; КонецЕсли; ОбластьЯчейки = Неопределено; РезультатЯчейки = Неопределено; НомерКолонкиДокумента = 0; Примечание = ""; СтандартнаяОбработка = Истина; ТекстЯчейки = ""; Если ЗначениеЗаполнено(СтрокаСопоставления.ИмяКолонкиИсточника) Тогда НомерКолонкиДокумента = Число(СтрокаСопоставления.ИмяКолонкиИсточника); ОбластьЯчейки = ЯчейкиСтроки[НомерКолонкиДокумента]; ТекстЯчейки = ТекстыЯчеек[НомерКолонкиДокумента]; КонецЕсли; ОригинальныйТекстЯчейки = ТекстЯчейки; РезультатЯчейки = СтрокаСопоставления.Значение; Если ЗначениеЗаполнено(СтрокаСопоставления.Алгоритм) Тогда Попытка АлгоритмОбъект = ирОбщий.ДесериализоватьАлгоритмОбъектЛкс(СтрокаСопоставления.Алгоритм); #Если Сервер И Не Сервер Тогда АлгоритмОбъект = Обработки.ирИмитаторАлгоритмОбъект.Создать(); #КонецЕсли Исключение ВызватьИсключение "Ошибка десериализации алгоритма вычисления значения колонки " + СтрокаСопоставления.ИмяКолонкиПриемника + ": " + ОписаниеОшибки(); КонецПопытки; ВнутренниеПараметры = АлгоритмОбъект.Параметры.Выгрузить(); АлгоритмОбъект.Параметры.Загрузить(мАлгоритмКонвертацииЗначенияПараметры); ирОбщий.ЗагрузитьВТаблицуЗначенийЛкс(ВнутренниеПараметры, АлгоритмОбъект.Параметры); Вычисление = ВычислитьЗначениеЯчейки(АлгоритмОбъект, РезультатыЯчеек, ТекстЯчейки, ТекстыЯчеек, РезультатЯчейки, Примечание, СтандартнаяОбработка); РезультатЯчейки = Вычисление.Результат; Примечание = Вычисление.ОписаниеОшибки; ТекстЯчейки = Вычисление.ТекстЯчейки; СтандартнаяОбработка = Вычисление.СтандартнаяОбработка; КонецЕсли; Если Истина И СтандартнаяОбработка И СтрокаСопоставления.РежимКонвертации = "ИзИсточника" И СтрокаСопоставления.Значение = РезультатЯчейки И ЗначениеЗаполнено(СтрокаСопоставления.ИмяКолонкиИсточника) Тогда Примечание = ОбработатьОбласть(ОбластьЯчейки, СтрокаСопоставления, РезультатыЯчеек, РазрешитьСозданиеОбъектов, КэшПоиска, ТекстЯчейки, РезультатЯчейки); Если ДобавлятьСырыеДанныеВТЗ Тогда РезультатыЯчеек.Вставить(СтрокаСопоставления.ИмяКолонкиПриемника + мСуффиксСырыхДанных, ОригинальныйТекстЯчейки); КонецЕсли; КонецЕсли; Если ЗначениеЗаполнено(Примечание) Тогда КоличествоОшибок = КоличествоОшибок + 1; Если ВыводитьОшибкиКонвертацииСразу Тогда ПредставлениеКраткое = ирОбщий.ПредставлениеЗначенияСОграничениемДлиныЛкс(ОригинальныйТекстЯчейки, 50); ирОбщий.СообщитьЛкс("Ячейка["+ОбластьЯчейки.Имя+"->"+СтрокаСопоставления.СинонимКолонкиПриемника+"](" + ПредставлениеКраткое + "): " + Примечание, СтатусСообщения.Внимание); КонецЕсли; Если РазрешитьСозданиеОбъектов И ЗначениеЗаполнено(СтрокаСопоставления.ИмяКолонкиИсточника) Тогда СтрокаОшибки = ОшибкиКонвертации.Добавить(); СтрокаОшибки.КолонкаИсточника = СтрокаСопоставления.ИмяКолонкиИсточника; СтрокаОшибки.Ошибка = Примечание; СтрокаОшибки.ТекстЯчейки = ОригинальныйТекстЯчейки; СтрокаОшибки.Количество = 1; КонецЕсли; КонецЕсли; РезультатыЯчеек.Вставить(СтрокаСопоставления.ИмяКолонкиПриемника, РезультатЯчейки); Если Истина И ОбластьЯчейки <> Неопределено И (Ложь Или ОбластьЯчейки.СодержитЗначение Или ЗначениеЗаполнено(Примечание)) Тогда // Используем флаг СодержитЗначение для обозначения наличия установленного нами примечания ОбластьЯчейки.Примечание.Текст = Примечание; // Первое обращение к Область.Примечание выполняется долго, второе в 2 раза быстрее но все равно долго ОбластьЯчейки.СодержитЗначение = ЗначениеЗаполнено(Примечание); КонецЕсли; КонецЦикла; КонецЦикла; Возврат РезультатыЯчеек; КонецФункции // Процедура выполняет обработку области табличного документа: // заполняет расшифровку по представлению ячейки в соответствии со структурой загружаемых реквизитов // сообщает об ошибке и устанавливает коментарий, если ячейка содержит ошибку // // Параметры: // Область - область табличного документа // Колонка - Структура, свойства, в соответствии с которыми необходимо выполнить обработку области // ТекущиеДанные - структура загруженных значений // ТекстыЯчеек - массив текстов ячеек строки // Функция ОбработатьОбласть(Знач Область, СтрокаСопоставления, ТекущиеДанные, РазрешитьСозданиеОбъектов, КэшПоиска, Представление, Результат) #Если Сервер И Не Сервер Тогда Область = Новый ТабличныйДокумент; Область = Область.Область(); #КонецЕсли Если СтрокаСопоставления.ОбрезатьКрайниеПробелы Тогда Представление = СокрЛП(Представление); КонецЕсли; Примечание = ""; Расшифровка = Область.Расшифровка; Если Истина И ТипЗнч(Расшифровка) <> Тип("Неопределено") И ТипЗнч(Расшифровка) <> Тип("Строка") И ТипЗнч(Расшифровка) <> Тип("ИдентификаторРасшифровкиКомпоновкиДанных") И СтрокаСопоставления.ОписаниеТипов.СодержитТип(ТипЗнч(Расшифровка)) И Не СтрокаСопоставления.ИгнорироватьРасшифровку Тогда Результат = Расшифровка; Если Результат <> СтрокаСопоставления.ОписаниеТипов.ПривестиЗначение(Результат) Тогда Примечание = "Расшифровка ячейки вне границ типа"; КонецЕсли; ИначеЕсли ПустаяСтрока(Представление) Тогда Результат = Неопределено; Иначе НайденныеЗначения = ПолучитьВозможныеЗначения(СтрокаСопоставления, Представление, Примечание, ТекущиеДанные, РазрешитьСозданиеОбъектов, КэшПоиска); Если НайденныеЗначения.Количество() = 0 Тогда Примечание = "Не найден" + ?(Примечание = "", "", Символы.ПС+Примечание); Результат = Неопределено; ИначеЕсли НайденныеЗначения.Количество() = 1 Тогда Результат = НайденныеЗначения[0]; Иначе Примечание = "Неоднозначное (" + НайденныеЗначения.Количество() + " вариантов) представление" +?(Примечание = "","", Символы.ПС+Примечание); Нашли = Ложь; НашлиЗначениеПоУмолчанию = Ложь; Для каждого НайденноеЗначение Из НайденныеЗначения Цикл Если НайденноеЗначение = Расшифровка Тогда Нашли = Истина; Прервать; КонецЕсли; Если НайденноеЗначение = СтрокаСопоставления.Значение Тогда НашлиЗначениеПоУмолчанию = Истина; КонецЕсли; КонецЦикла; Если Не Нашли Тогда Если НашлиЗначениеПоУмолчанию Тогда НайденноеЗначение = СтрокаСопоставления.Значение; Иначе НайденноеЗначение = НайденныеЗначения[0]; КонецЕсли; КонецЕсли; Результат = НайденноеЗначение; Если Не СтрокаСопоставления.ОписаниеТипов.СодержитТип(ТипЗнч(Расшифровка)) Тогда Область.Расшифровка = Новый СписокЗначений; Область.Расшифровка.Добавить(НайденноеЗначение); КонецЕсли; КонецЕсли; КонецЕсли; Если НЕ ЗначениеЗаполнено(Результат) Тогда Результат = СтрокаСопоставления.Значение; КонецЕсли; Возврат Примечание; КонецФункции // Функция возвращает массив возможных значений для текущей колонки по представлению // // Параметры: // Колонка - Структура, свойства, в соответствии с которыми необходимо получить возможные значения // Представление - Строка, по которой необходимо вернуть массив значений // Примечание - массив текстов ячеек строки // ТекущиеДанные - структура загруженных значений // // Возвращаемое значение: // массив возможных значений // Функция ПолучитьВозможныеЗначения(Знач ОписаниеКолонки, Знач Представление, выхПримечание, Знач ТекущиеДанные, Знач РазрешитьСозданиеОбъектов = Ложь, КэшПоиска = Неопределено) выхПримечание = ""; НайденныеЗначения = Новый Массив; Если ПустаяСтрока(Представление) Тогда Возврат НайденныеЗначения; КонецЕсли; ОписаниеТипов = ОписаниеКолонки.ОписаниеТипов; СвязьПоТипу = Неопределено; Если Не ПустаяСтрока(ОписаниеКолонки.СвязьПоТипу) Тогда Если ТипЗНЧ(ОписаниеКолонки.СвязьПоТипу) = Тип("Строка") Тогда Если Не ТекущиеДанные.Свойство(ОписаниеКолонки.СвязьПоТипу, СвязьПоТипу) Тогда выхПримечание = выхПримечание + Символы.ПС + ирОбщий.СтрШаблонИменЛкс("Колонка %1 связи по типу не найдена",, ОписаниеКолонки.СвязьПоТипу); КонецЕсли; Иначе СвязьПоТипу = ОписаниеКолонки.СвязьПоТипу; КонецЕсли; Если Не СвязьПоТипу = Неопределено Тогда ЭлементСвязиПоТипу = ОписаниеКолонки.ЭлементСвязиПоТипу; Если ЭлементСвязиПоТипу = 0 Тогда ЭлементСвязиПоТипу = 1; КонецЕсли; ВидыСубконто = СвязьПоТипу.ВидыСубконто; Если ЭлементСвязиПоТипу > ВидыСубконто.Количество() Тогда Возврат НайденныеЗначения; КонецЕсли; ОписаниеТипов = СвязьПоТипу.ВидыСубконто[ЭлементСвязиПоТипу-1].ВидСубконто.ТипЗначения; КонецЕсли; КонецЕсли; #Если Сервер И Не Сервер Тогда ОписаниеТипов = Новый ОписаниеТипов; #КонецЕсли ТипыЗначений = ОписаниеТипов.Типы(); Если ОписаниеКолонки.СодержитСсылки Тогда Если КэшПоиска = Неопределено Тогда КэшПоиска = Новый Соответствие; КонецЕсли; КэшПоискаКолонки = КэшПоиска[ОписаниеКолонки]; Если КэшПоискаКолонки = Неопределено Тогда КэшПоискаКолонки = Новый Соответствие; КэшПоиска[ОписаниеКолонки] = КэшПоискаКолонки; КонецЕсли; Значение = ирОбщий.НавигационнаяСсылкаВЗначениеЛкс(Представление); Если Не ЗначениеЗаполнено(Значение) Тогда Значение = ирОбщий.ПреобразоватьЗначениеИзSDBLЛкс(Представление); КонецЕсли; КонецЕсли; Если Истина И ЗначениеЗаполнено(Значение) И (Ложь Или ТипыЗначений.Количество() = 0 Или ОписаниеТипов.СодержитТип(ТипЗнч(Значение))) Тогда НайденныеЗначения.Добавить(Значение); Иначе Если ОписаниеКолонки.СодержитСсылки Тогда ПеречисленияВсеТипы = Перечисления.ТипВсеСсылки(); ДокументыВсеТипы = Документы.ТипВсеСсылки(); КонецЕсли; Для каждого ТипРеквизита Из ТипыЗначений Цикл Если ТипРеквизита = ПримитивныеТипы.Строка Тогда Если Истина И ОписаниеТипов.КвалификаторыСтроки.Длина > 0 И СтрДлина(Представление) > ОписаниеТипов.КвалификаторыСтроки.Длина Тогда выхПримечание = "Строковое значение превышает допустимую длину"; КонецЕсли; НайденныеЗначения.Добавить(Представление); ИначеЕсли Ложь Или ТипРеквизита = ПримитивныеТипы.Число Или ТипРеквизита = ПримитивныеТипы.Булево Тогда НайденныеЗначения.Добавить(ирОбщий.СтрокаВЧислоЛкс(Представление, ОписаниеКолонки.ОписаниеТипов, выхПримечание)); ИначеЕсли ТипРеквизита = ПримитивныеТипы.Дата Тогда НайденныеЗначения.Добавить(ирОбщий.СтрокаВДатуЛкс(Представление, ОписаниеКолонки.ОписаниеТипов, выхПримечание, ОписаниеКолонки.АмериканскоеПоложениеМесяца)); ИначеЕсли ТипРеквизита = Тип("УникальныйИдентификатор") Тогда НайденныеЗначения.Добавить(мПривестиКУникальномуИдентификатору(Представление, выхПримечание)); ИначеЕсли ТипРеквизита = Тип("ОписаниеТипов") Тогда НайденныеЗначения.Добавить(мПривестиКОписаниюТипов(Представление, выхПримечание)); ИначеЕсли ТипРеквизита = Тип("Null") Тогда НайденныеЗначения.Добавить(Null); Иначе ОбъектМД = Метаданные.НайтиПоТипу(ТипРеквизита); Если ПеречисленияВсеТипы.СодержитТип(ТипРеквизита) Тогда //Это Перечисление Для каждого ЗначениеПеречисления Из ирОбщий.ПолучитьМенеджерЛкс(ТипРеквизита) Цикл Если ОписаниеКолонки.ИскатьПо = "Имя" Тогда КлючЗначенияПеречисления = XMLСтрока(ЗначениеПеречисления); Иначе КлючЗначенияПеречисления = Строка(ЗначениеПеречисления); КонецЕсли; Если ирОбщий.СтрокиРавныЛкс(КлючЗначенияПеречисления, Представление) Тогда НайденныеЗначения.Добавить(ЗначениеПеречисления); КонецЕсли; КонецЦикла; ИначеЕсли ДокументыВсеТипы.СодержитТип(ТипРеквизита) Тогда СписокДокументов = ирОбщий.ПреобразоватьПредставлениеВСсылкуЛкс(ОбъектМД, Представление, ТипыЗначений.Количество() > 1, КэшПоискаКолонки); Если СписокДокументов <> Неопределено Тогда Если ТипЗнч(СписокДокументов) = Тип("СписокЗначений") Тогда Для Каждого ЭлементСписка Из СписокДокументов Цикл НайденныеЗначения.Добавить(ЭлементСписка.Значение); КонецЦикла; Иначе НайденныеЗначения.Добавить(СписокДокументов); КонецЕсли; КонецЕсли; ИначеЕсли ОбъектМД <> Неопределено Тогда ИскатьПо = ОписаниеКолонки.ИскатьПо; Если ИскатьПо = "Идентификатор" Тогда НайденныеЗначения.Добавить(ирОбщий.ПреобразоватьПредставлениеВСсылкуЛкс(ОбъектМД, Представление)); Иначе СтруктураОтбора = Новый Структура; ПоляТаблицыБД = ирКэш.ПоляТаблицыБДЛкс(ОбъектМД.ПолноеИмя()); ЭтоСправочник = Справочники.ТипВсеСсылки().СодержитТип(ТипРеквизита); Если ПустаяСтрока(ИскатьПо) Или ПоляТаблицыБД.Найти(ИскатьПо) = Неопределено Тогда СтрокаОсновногоПредставления = Строка(ОбъектМД.ОсновноеПредставление); Если СтрокаОсновногоПредставления = "ВВидеКода" Тогда ИскатьПо = "Код"; ИначеЕсли СтрокаОсновногоПредставления = "ВВидеНаименования" Тогда ИскатьПо = "Наименование"; ИначеЕсли СтрокаОсновногоПредставления = "ВВидеНомера" Тогда ИскатьПо = "Номер"; Иначе ВызватьИсключение "Отсутствует ключ поиска"; КонецЕсли; КонецЕсли; СтруктураОтбора.Вставить(ИскатьПо, Представление); Если Истина И ЭтоСправочник И Не ПустаяСтрока(ОписаниеКолонки.СвязьПоВладельцу) И ОписаниеКолонки.СвязьПоВладельцу <> "<Создаваемый объект>" И ОбъектМД.Владельцы.Количество() > 0 Тогда СвязьПоВладельцу = Неопределено; Если ТипЗНЧ(ОписаниеКолонки.СвязьПоВладельцу) = Тип("Строка") Тогда Если Не ТекущиеДанные.Свойство(ОписаниеКолонки.СвязьПоВладельцу, СвязьПоВладельцу) Тогда выхПримечание = выхПримечание + Символы.ПС + ирОбщий.СтрШаблонИменЛкс("Колонка %1 связи по владельцу не найдена",, ОписаниеКолонки.СвязьПоВладельцу); КонецЕсли; Иначе СвязьПоВладельцу = ОписаниеКолонки.СвязьПоВладельцу; КонецЕсли; Если Истина И СвязьПоВладельцу <> Неопределено И ПоляТаблицыБД.Найти("Владелец").ТипЗначения.СодержитТип(ТипЗнч(СвязьПоВладельцу)) Тогда СтруктураОтбора.Вставить("Владелец", СвязьПоВладельцу); КонецЕсли; КонецЕсли; КлючКэша = ОбъектМД.ПолноеИмя() + "." + ирОбщий.ОбъектВСтрокуJSONЛкс(СтруктураОтбора); НайденныеЗначения = КэшПоискаКолонки[КлючКэша]; Если НайденныеЗначения = Неопределено Тогда НайденныеЗначения = Новый Массив; Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ ПЕРВЫЕ 10 | _Таблица.Ссылка |ИЗ | " + ОбъектМД.ПолноеИмя() + " КАК _Таблица |ГДЕ"; Для Каждого КлючИЗначение Из СтруктураОтбора Цикл Запрос.Параметры.Вставить(КлючИЗначение.Ключ, КлючИЗначение.Значение); Запрос.Текст = Запрос.Текст + " | _Таблица." + ИскатьПо + " = &" + КлючИЗначение.Ключ; КонецЦикла; Выборка = Запрос.Выполнить().Выбрать(); Пока Выборка.Следующий() Цикл НайденныеЗначения.Добавить(Выборка.Ссылка); КонецЦикла; Если Истина И РазрешитьСозданиеОбъектов И ОписаниеКолонки.СоздаватьЕслиНеНайден И НайденныеЗначения.Количество() = 0 Тогда НовыйОбъект = ирОбщий.ОбъектБДПоКлючуЛкс(ОбъектМД.ПолноеИмя()); ЗаполнитьЗначенияСвойств(НовыйОбъект.Данные, СтруктураОтбора); Попытка ирОбщий.ЗаписатьОбъектЛкс(НовыйОбъект.Методы,,,, Ложь,,,, Истина); Исключение ИнформацияОбОшибке = ИнформацияОбОшибке(); выхПримечание = "Ошибка создания объекта: " + КраткоеПредставлениеОшибки(ИнформацияОбОшибке); КонецПопытки; Если ЗначениеЗаполнено(НовыйОбъект.Методы.Ссылка) Тогда НайденныеЗначения.Добавить(НовыйОбъект.Методы.Ссылка); ирОбщий.СообщитьЛкс(ирОбщий.СтрШаблонЛкс("Создан элемент ""%1"" в справочнике ""%2"" для колонки ""%3""", Представление, ОбъектМД.Имя, ОписаниеКолонки.ИмяКолонкиПриемника)); КонецЕсли; КонецЕсли; КэшПоискаКолонки[КлючКэша] = НайденныеЗначения; КонецЕсли; КонецЕсли; Иначе выхПримечание = выхПримечание + Символы.ПС + ирОбщий.СтрШаблонИменЛкс("Для типа значения %1 не описан способ поиска",, ТипРеквизита); КонецЕсли; КонецЕсли; КонецЦикла; КонецЕсли; Если Лев(выхПримечание, 1) = Символы.ПС Тогда выхПримечание = Сред(выхПримечание, 2); КонецЕсли; Возврат НайденныеЗначения; КонецФункции Функция мПолучитьНастройку(ДляФайла = Ложь) Экспорт #Если Сервер И Не Сервер Тогда ТабличныйДокумент = Новый ТабличныйДокумент; #КонецЕсли ДокументРезультат = Новый Структура; ДокументРезультат.Вставить("ВыводитьОшибкаЗагрузкиСразу", ВыводитьОшибкаЗагрузкиСразу); ДокументРезультат.Вставить("ВыводитьОшибкиКонвертацииСразу", ВыводитьОшибкиКонвертацииСразу); ДокументРезультат.Вставить("ДополнятьЗапросом", ДополнятьЗапросом); ДокументРезультат.Вставить("ДобавлятьСтрокиБД", ДобавлятьСтрокиБД); ДокументРезультат.Вставить("ОбновлятьСтрокиБД", ОбновлятьСтрокиБД); ДокументРезультат.Вставить("ВыполнятьЗагрузкуНаСервере", ВыполнятьЗагрузкуНаСервере); ДокументРезультат.Вставить("ВыполнятьКонвертациюНаСервере", ВыполнятьКонвертациюНаСервере); ДокументРезультат.Вставить("КоличествоПотоков", КоличествоПотоков); ДокументРезультат.Вставить("КоличествоОбъектовВПорции", КоличествоОбъектовВПорции); ДокументРезультат.Вставить("ПолноеИмяТаблицы", мТекущееПолноеИмяТаблицы); // Для загрузки настройки из файла ДокументРезультат.Вставить("СобытияОбработкиОбъектов", СобытияОбработкиОбъектов.Скопировать(, "ИмяСобытия, Алгоритм")); ДокументРезультат.Вставить("ПерваяСтрокаДанныхТД", ПерваяСтрокаДанныхТД); ДокументРезультат.Вставить("ПоследняяСтрокаДанныхТД", ПоследняяСтрокаДанныхТД); ДокументРезультат.Вставить("СтрокаЗаголовковТД", СтрокаЗаголовковТД); ДокументРезультат.Вставить("СопоставлениеКолонокТЗ", СопоставлениеКолонокТЗ.Скопировать()); ДокументРезультат.Вставить("СопоставлениеКолонокБД", СопоставлениеКолонокБД.Скопировать()); ДокументРезультат.Вставить("НастройкаКомпоновки", ТаблицаЗначенийКомпоновщик.ПолучитьНастройки()); ДокументРезультат.Вставить("ТаблицаЗначенийИспользоватьОтбор", ТаблицаЗначенийИспользоватьОтбор); ДокументРезультат.Вставить("ДобавлятьСырыеДанныеВТЗ", ДобавлятьСырыеДанныеВТЗ); ДокументРезультат.Вставить("АвтоДобавлениеКолонокТЗИзБД", АвтоДобавлениеКолонокТЗИзБД); ДокументРезультат.Вставить("ДополнениеЗапросом", мДополнениеЗапросом); ДокументРезультат.Вставить("СвязиИПараметрыВыбора", СвязиИПараметрыВыбора); СтруктураПозицийТД = СтруктураПозицийТД(); Если ДляФайла Или СохранятьДанныеТД Тогда ДокументРезультат.Вставить("ТабличныйДокумент", ТабличныйДокумент.ПолучитьОбласть()); Если Не ДляФайла И ТабличныйДокумент.ВысотаТаблицы > 1000 Тогда ирОбщий.СообщитьЛкс("В хранилище настроек БД помещено большое количество строк табличного документа. Рекомендуется хранить такие настройки в файлах"); КонецЕсли; ДокументРезультат.Вставить("ОшибкиКонвертации", ОшибкиКонвертации.Выгрузить()); ИначеЕсли ЗначениеЗаполнено(СтруктураПозицийТД.НомерСтрокиЗаголовков) Тогда ДокументРезультат.Вставить("ТабличныйДокумент", ТабличныйДокумент.ПолучитьОбласть(СтруктураПозицийТД.НомерСтрокиЗаголовков, 1, СтруктураПозицийТД.НомерСтрокиЗаголовков, ТабличныйДокумент.ШиринаТаблицы)); Иначе ДокументРезультат.Вставить("ТабличныйДокумент", Новый ТабличныйДокумент); КонецЕсли; Если ДляФайла Или СохранятьДанныеТЗ Тогда ДокументРезультат.Вставить("ТаблицаЗначений", ТаблицаЗначений.Скопировать()); Если Не ДляФайла И ТаблицаЗначений.Количество() > 5000 Тогда ирОбщий.СообщитьЛкс("В хранилище настроек БД помещено большое количество строк таблицы значений. Рекомендуется хранить такие настройки в файлах"); КонецЕсли; Иначе ДокументРезультат.Вставить("ТаблицаЗначений", ТаблицаЗначений.СкопироватьКолонки()); КонецЕсли; Возврат ДокументРезультат; КонецФункции // () Процедура мЗагрузитьНастройку(Настройка, ЗаменитьДанныеТДиТЗ = Истина, ЗаменитьМетаданныеТДиТЗ = Истина) Экспорт #Если Сервер И Не Сервер Тогда Настройка = Новый Структура; #КонецЕсли мДополнениеЗапросом = Неопределено; Если Настройка <> Неопределено Тогда Если ЗаменитьДанныеТДиТЗ Тогда Если Настройка.Свойство("ШапкаТабличногоДокумента") Тогда // Старый формат НовыйТабличныйДокумент = Настройка.ШапкаТабличногоДокумента; Иначе НовыйТабличныйДокумент = Настройка.ТабличныйДокумент; КонецЕсли; // Это нужно делать до загрузки свойства СохранятьДанныеТД через ЗаполнитьЗначенияСвойств! ТабличныйДокумент.Очистить(); ТабличныйДокумент.Вывести(НовыйТабличныйДокумент); ОшибкиКонвертации.Очистить(); КонецЕсли; Если Не Настройка.Свойство("ДополнятьЗапросом") Тогда Настройка.Вставить("ДополнятьЗапросом", Ложь); КонецЕсли; Если Не Настройка.Свойство("АвтоДобавлениеКолонокТЗИзБД") Тогда Настройка.Вставить("АвтоДобавлениеКолонокТЗИзБД", Ложь); КонецЕсли; Если Не Настройка.Свойство("СвязиИПараметрыВыбора") Тогда Настройка.Вставить("СвязиИПараметрыВыбора", Истина); КонецЕсли; Если Не Настройка.Свойство("ДополнениеЗапросом") Тогда Настройка.Вставить("ДополнениеЗапросом"); КонецЕсли; Если Не Настройка.Свойство("НастройкаКомпоновки") Тогда Настройка.Вставить("НастройкаКомпоновки", Новый НастройкиКомпоновкиДанных); КонецЕсли; Если Не Настройка.Свойство("ПоследняяСтрокаДанныхТД") Тогда Настройка.Вставить("ПоследняяСтрокаДанныхТД"); КонецЕсли; Если Не ЗаменитьДанныеТДиТЗ Тогда Настройка.Удалить("СтрокаЗаголовковТД"); Настройка.Удалить("ПерваяСтрокаДанныхТД"); Настройка.Удалить("ПоследняяСтрокаДанныхТД"); КонецЕсли; ЗаполнитьЗначенияСвойств(ЭтотОбъект, Настройка,, "АвтоДобавлениеКолонокТЗИзБД, ТабличныйДокумент, ТаблицаЗначений, СобытияОбработкиОбъектов, СопоставлениеКолонокТЗ, СопоставлениеКолонокБД, ПолноеИмяТаблицы, ДополнятьЗапросом"); Если ЗаменитьДанныеТДиТЗ Тогда ТаблицаЗначений.Очистить(); ЭтотОбъект.ТаблицаЗначений = Настройка.ТаблицаЗначений.Скопировать(); КонецЕсли; Если ЗаменитьМетаданныеТДиТЗ Тогда ЭтотОбъект.АвтоДобавлениеКолонокТЗИзБД = Настройка.АвтоДобавлениеКолонокТЗИзБД; СобытияОбработкиОбъектов.ЗаполнитьЗначения(, "Алгоритм, АлгоритмОбъект"); Если Настройка.Свойство("СобытияОбработкиОбъектов") Тогда Для Каждого СохраненнаяСтрокаСобытияОбработкиОбъектов Из Настройка.СобытияОбработкиОбъектов Цикл СтрокаСобытияОбработкиОбъектов = СобытияОбработкиОбъектов.Найти(СохраненнаяСтрокаСобытияОбработкиОбъектов.ИмяСобытия, "ИмяСобытия"); СтрокаСобытияОбработкиОбъектов.Алгоритм = СохраненнаяСтрокаСобытияОбработкиОбъектов.Алгоритм; КонецЦикла; КонецЕсли; КонецЕсли; Если Ложь Или ЗаменитьМетаданныеТДиТЗ Или АвтоДобавлениеКолонокТЗИзБД И ЗначениеЗаполнено(ПолноеИмяТаблицы) Тогда ирОбщий.ЗагрузитьВТаблицуЗначенийЛкс(Настройка.СопоставлениеКолонокТЗ, СопоставлениеКолонокТЗ,,, Истина); // Конвертация из старого формата настроек Для Каждого СтрокаСопоставления Из СопоставлениеКолонокТЗ.НайтиСтроки(Новый Структура("РежимКонвертации", "Искать")) Цикл СтрокаСопоставления.РежимКонвертации = "ИзИсточника"; КонецЦикла; Для Каждого СтрокаСопоставления Из СопоставлениеКолонокТЗ.НайтиСтроки(Новый Структура("РежимКонвертации", "Вычислять")) Цикл СтрокаСопоставления.РежимКонвертации = "Устанавливать"; КонецЦикла; мДополнениеЗапросом = Настройка.ДополнениеЗапросом; ЭтотОбъект.ДополнятьЗапросом = мДополнениеЗапросом <> Неопределено И Настройка.ДополнятьЗапросом; ТаблицаЗначенийКомпоновщик.ЗагрузитьНастройки(Настройка.НастройкаКомпоновки); КонецЕсли; Если Настройка.Свойство("ПолноеИмяТаблицы") И ирОбщий.СтрокиРавныЛкс(Настройка.ПолноеИмяТаблицы, ПолноеИмяТаблицы) Тогда ирОбщий.ЗагрузитьВТаблицуЗначенийЛкс(Настройка.СопоставлениеКолонокБД, СопоставлениеКолонокБД,,, Истина); ЗаполнитьСопоставлениеКолонокБД(); КонецЕсли; Если АвтоДобавлениеКолонокТЗИзБД И ЗначениеЗаполнено(ПолноеИмяТаблицы) Тогда ОбновитьКолонкиТаблицыЗначений(Ложь, Истина); КонецЕсли; Если Настройка.Свойство("ОшибкиКонвертации") Тогда ирОбщий.ЗагрузитьВТаблицуЗначенийЛкс(Настройка.ОшибкиКонвертации, ОшибкиКонвертации,,, Истина); ОбновитьОшибкиКонвертацииПриИзмененииСоставаКолонокТЗ(); КонецЕсли; Иначе Если ЗаменитьМетаданныеТДиТЗ Тогда ЭтотОбъект.АвтоДобавлениеКолонокТЗИзБД = ЗначениеЗаполнено(ПолноеИмяТаблицы); КонецЕсли; Если АвтоДобавлениеКолонокТЗИзБД И ЗначениеЗаполнено(ПолноеИмяТаблицы)Тогда ОбновитьКолонкиТаблицыЗначений(Истина, Истина); КонецЕсли; КонецЕсли; СопоставлениеКолонокТЗЗаполнить(Настройка <> Неопределено); СопоставлениеКолонокБДЗаполнитьПоИменамСинонимам(Настройка <> Неопределено); КонецПроцедуры // Функция возвращает список, элементами которого выступают возможные имена представления загружаемого реквизита // // Параметры: // ЗагружаемыйРеквизит - Строка таблицы значений загружаемого реквизита // // Возвращаемое значение: // список значений; значение списка - строка имя представления // Функция ПолучитьСписокИменПредставлений(ЗагружаемыйРеквизит) Экспорт СписокВыбора = Новый СписокЗначений; Если ЗагружаемыйРеквизит.ОписаниеТипов.Типы().Количество() = 1 Тогда Тип = ЗагружаемыйРеквизит.ОписаниеТипов.Типы()[0]; МетаданныеТипа = Метаданные.НайтиПоТипу(Тип); Если МетаданныеТипа <> Неопределено Тогда ПолноеИмяМД = МетаданныеТипа.ПолноеИмя(); КорневойТип = ирОбщий.ПервыйФрагментЛкс(ПолноеИмяМД); КонецЕсли; ЭтоСправочник = Справочники.ТипВсеСсылки().СодержитТип(Тип); ЭтоСчет = ПланыСчетов.ТипВсеСсылки().СодержитТип(Тип); ЭтоВидХарактеристик = ПланыВидовХарактеристик.ТипВсеСсылки().СодержитТип(Тип); Если ЭтоСправочник ИЛИ ЭтоСчет Или ЭтоВидХарактеристик Тогда ЕстьКод = МетаданныеТипа.ДлинаКода > 0; ЕстьИмя = МетаданныеТипа.ДлинаНаименования > 0; ВидОсновногоПредставление = ?(ЭтоСправочник, Метаданные.СвойстваОбъектов.ОсновноеПредставлениеСправочника, ?(ЭтоСчет,Метаданные.СвойстваОбъектов.ОсновноеПредставлениеСчета,Метаданные.СвойстваОбъектов.ОсновноеПредставлениеВидаХарактеристики)); Если МетаданныеТипа.ОсновноеПредставление = ВидОсновногоПредставление.ВВидеКода Тогда Если ЕстьКод Тогда СписокВыбора.Добавить("Код", "Код"); КонецЕсли; Если ЕстьИмя Тогда СписокВыбора.Добавить("Наименование", "Наименование"); КонецЕсли; Иначе Если ЕстьИмя Тогда СписокВыбора.Добавить("Наименование", "Наименование"); КонецЕсли; Если ЕстьКод Тогда СписокВыбора.Добавить("Код", "Код"); КонецЕсли; КонецЕсли; Для каждого Реквизит Из МетаданныеТипа.Реквизиты Цикл Если Не Реквизит.Индексирование = Метаданные.СвойстваОбъектов.Индексирование.НеИндексировать И Реквизит.Тип.Типы().Количество() = 1 и Реквизит.Тип.Типы()[0] = Тип ("Строка") Тогда СписокВыбора.Добавить(Реквизит.Имя, Реквизит.Представление()); КонецЕсли; КонецЦикла; КонецЕсли; Если ирОбщий.ЛиКорневойТипПеречисленияЛкс(КорневойТип) Тогда СписокВыбора.Добавить("Синоним"); СписокВыбора.Добавить("Имя"); ИначеЕсли Документы.ТипВсеСсылки().СодержитТип(Тип) Тогда СписокВыбора.Добавить("Авто", "<Авто>"); ИначеЕсли МетаданныеТипа <> Неопределено Тогда СписокВыбора.Добавить("Идентификатор", "<Идентификатор>"); КонецЕсли; КонецЕсли; Возврат СписокВыбора; КонецФункции Функция СписокСвязейКолонкиПоВладельцу(ЗагружаемыйРеквизит) Экспорт ЕстьТипСамогоОбъекта = Ложь; Если мЭтоСсылочныйОбъект Тогда ОписаниеТиповСправочника = Тип(ирОбщий.ИмяТипаИзПолногоИмениМДЛкс(ПолноеИмяТаблицы)); КонецЕсли; СписокВыбора = Новый СписокЗначений; ТипыВладельцев = Новый Соответствие; Для каждого ТипКолонки Из ЗагружаемыйРеквизит.ОписаниеТипов.Типы() Цикл Если Справочники.ТипВсеСсылки().СодержитТип(ТипКолонки) Тогда Для каждого Владелец Из Метаданные.НайтиПоТипу(ТипКолонки).Владельцы Цикл ТипВладельца = Тип(ирОбщий.ИмяТипаИзПолногоИмениМДЛкс(Владелец.ПолноеИмя())); Если ТипыВладельцев[ТипВладельца] = Неопределено Тогда Если ТипВладельца = ОписаниеТиповСправочника Тогда ЕстьТипСамогоОбъекта = Истина; КонецЕсли; ТипыВладельцев.Вставить(ТипВладельца, Владелец.ПолноеИмя()); Для каждого КолонкаСвязиПоВладельцу Из СопоставлениеКолонокТЗ Цикл Если Истина И КолонкаСвязиПоВладельцу.ОписаниеТипов.СодержитТип(ТипВладельца) И СписокВыбора.НайтиПоЗначению(КолонкаСвязиПоВладельцу.ИмяКолонкиПриемника) = Неопределено Тогда СписокВыбора.Добавить(КолонкаСвязиПоВладельцу.ИмяКолонкиПриемника, КолонкаСвязиПоВладельцу.ИмяКолонкиПриемника); КонецЕсли; КонецЦикла; КонецЕсли; КонецЦикла; КонецЕсли; КонецЦикла; Если Не ТипыВладельцев.Количество() = 0 Тогда СписокВыбора.Добавить(Неопределено, "<пустое значение>"); КонецЕсли; Для каждого КлючИЗначение Из ТипыВладельцев Цикл СписокВыбора.Добавить(ирОбщий.ИмяТипаИзПолногоИмениМДЛкс(КлючИЗначение.Значение), "<"+КлючИЗначение.Значение+">"); КонецЦикла; Если ЕстьТипСамогоОбъекта Тогда СписокВыбора.Вставить(0, "<Создаваемый объект>", "<Создаваемый объект>"); КонецЕсли; Возврат СписокВыбора; КонецФункции // () // Функция возвращает список, элементами которого выступают возможные связи по типу для загружаемого реквизита // // Параметры: // ЗагружаемыйРеквизит - Строка таблицы значений загружаемого реквизита // // Возвращаемое значение: // список значений; значение списка - строка имя колонки связи или ссылка на элемент связи // Функция СписокСвязейКолонкиПоТипу(ЗагружаемыйРеквизит) Экспорт СписокВыбора = Новый СписокЗначений; ВозможныеПланыСчетов = Новый Структура; Для каждого ПланСчетов Из Метаданные.ПланыСчетов Цикл Если Истина И ПланСчетов.ВидыСубконто <> Неопределено И ирОбщий.ЛиОписаниеТипов1ВходитВОписаниеТипов2Лкс(ЗагружаемыйРеквизит.ОписаниеТипов, ПланСчетов.ВидыСубконто.Тип) Тогда ВозможныеПланыСчетов.Вставить(ПланСчетов.Имя, ПланыСчетов[ПланСчетов.Имя]); КонецЕсли; КонецЦикла; Для каждого ПланСчетов Из ВозможныеПланыСчетов Цикл ТипЗНЧПланСчетов = ТипЗнч(ПланСчетов.Значение.ПустаяСсылка()); Для каждого КолонкаСвязиПоТипу Из СопоставлениеКолонокТЗ Цикл Если КолонкаСвязиПоТипу.ОписаниеТипов.Типы()[0] = ТипЗНЧПланСчетов Тогда СписокВыбора.Добавить(КолонкаСвязиПоТипу.ИмяКолонкиПриемника, КолонкаСвязиПоТипу.ИмяКолонкиПриемника); КонецЕсли; КонецЦикла; КонецЦикла; Если Не ВозможныеПланыСчетов.Количество() = 0 Тогда СписокВыбора.Добавить(Неопределено, "< пустое значение >"); КонецЕсли; Для каждого ПланСчетов Из ВозможныеПланыСчетов Цикл СписокВыбора.Добавить("ПланСчетовСсылка."+ПланСчетов.Ключ, "<"+ПланСчетов.Ключ+">"); КонецЦикла; Возврат СписокВыбора; КонецФункции Процедура ЗаполнитьСопоставлениеКолонокБД() Экспорт КопияСопоставления = СопоставлениеКолонокБД.Скопировать(); СопоставлениеКолонокБД.Очистить(); Если Не ЗначениеЗаполнено(ПолноеИмяТаблицы) Тогда Возврат; КонецЕсли; МетаданныеИсточника = МетаданныеТаблицыБД(); ПоляТаблицы = ирОбщий.ПоляТаблицыМДЛкс(ПолноеИмяТаблицы); СтруктураКлючаОбъекта = ирОбщий.СтруктураКлючаТаблицыБДЛкс(ПолноеИмяТаблицы, Ложь); МассивВозможныхПолейПоиска = Новый Массив; МассивВозможныхПолейПоиска.Добавить("Код"); МассивВозможныхПолейПоиска.Добавить("Наименование"); МассивВозможныхПолейПоиска.Добавить("Период"); МассивВозможныхПолейПоиска.Добавить("Регистратор"); МассивВозможныхПолейПоиска.Добавить("НомерСтроки"); МассивВозможныхПолейПоиска.Добавить("Ссылка"); МассивВозможныхПолейПоиска.Добавить("Номер"); МассивВозможныхПолейПоиска.Добавить("Владелец"); МассивВозможныхПолейПоиска.Добавить("Дата"); МассивВозможныхПолейПоиска.Добавить("Родитель"); МассивВозможныхПолейПоиска.Добавить("ЭтоГруппа"); ТипТаблицыБД = ирОбщий.ТипТаблицыБДЛкс(ПолноеИмяТаблицы); Если ирОбщий.ЛиКорневойТипРегистраБДЛкс(ТипТаблицыБД) Тогда Для каждого МетаИзмерение Из МетаданныеИсточника.Измерения Цикл МассивВозможныхПолейПоиска.Добавить(МетаИзмерение.Имя); КонецЦикла; КонецЕсли; Для Каждого ПолеТаблицы Из ПоляТаблицы Цикл Если Ложь Или ПолеТаблицы.ТипЗначения.СодержитТип(Тип("ТаблицаЗначений")) //Или ПолеТаблицы.ТипЗначения.СодержитТип(Тип("ХранилищеЗначения")) //Или (Истина // И ПолеТаблицы.Метаданные = Неопределено // И (Ложь // Или ПолеТаблицы.Имя = "ВерсияДанных" // Или ПолеТаблицы.Имя = "Предопределенный")) Тогда Продолжить; КонецЕсли; ЗагружаемыйРеквизит = СопоставлениеКолонокБД.Добавить(); ЗагружаемыйРеквизит.ИмяКолонкиПриемника = ПолеТаблицы.Имя; ЗагружаемыйРеквизит.СинонимКолонкиПриемника = ПолеТаблицы.Заголовок; ЗагружаемыйРеквизит.ОписаниеТиповПриемника = ПолеТаблицы.ТипЗначения; ЗагружаемыйРеквизит.ДоступноИзменение = Истина И Не (Истина И ирОбщий.ЛиТипВложеннойТаблицыБДЛкс(ТипТаблицыБД) И (Ложь Или ПолеТаблицы.Имя = "Ссылка" Или ПолеТаблицы.Имя = "НомерСтроки")) И (Ложь Или Не мЭтоСсылочныйОбъект Или Не ирОбщий.НедоступноИзменениеПоляСсылочногоОбъектаЛкс(ПолеТаблицы.Имя)); Если ирОбщий.ЛиМетаданныеОбъектаСГруппамиЛкс(МетаданныеИсточника) Тогда Если Истина И ТипЗнч(ПолеТаблицы.Метаданные) = Тип("ОбъектМетаданных") И (Ложь Или ирКэш.НомерВерсииПлатформыЛкс() < 802014 Или Метаданные.ОбщиеРеквизиты.Найти(ПолеТаблицы.Метаданные.Имя) = Неопределено) Тогда ЗагружаемыйРеквизит.Принадлежность = ПолеТаблицы.Метаданные.Использование; Иначе ЗагружаемыйРеквизит.Принадлежность = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляГруппыИЭлемента; КонецЕсли; КонецЕсли; Если СтруктураКлючаОбъекта.Свойство(ПолеТаблицы.Имя) Тогда ЗагружаемыйРеквизит.Ключевое = Истина; ЗагружаемыйРеквизит.ПолеПоиска = Не мЭтоСсылочныйОбъект; КонецЕсли; Если ПолеТаблицы.Метаданные <> Неопределено Тогда ЗагружаемыйРеквизит.Подсказка = ПолеТаблицы.Метаданные.Подсказка; ЗагружаемыйРеквизит.Обязательное = ПолеТаблицы.Метаданные.ПроверкаЗаполнения = ПроверкаЗаполнения.ВыдаватьОшибку; КонецЕсли; ЗагружаемыйРеквизит.Значение = ЗагружаемыйРеквизит.ОписаниеТиповПриемника.ПривестиЗначение(Неопределено); ВосстановитьИзменяемыеСвойстваСтрокиСопоставленияБД(ЗагружаемыйРеквизит, КопияСопоставления); Если СтруктураКлючаОбъекта.Свойство(ПолеТаблицы.Имя) Тогда ЗагружаемыйРеквизит.Пометка = Не мЭтоСсылочныйОбъект; //ЗагружаемыйРеквизит.ПолеПоиска = Не мЭтоСсылочныйОбъект; КонецЕсли; КонецЦикла; Если ирОбщий.ЛиКорневойТипСсылочногоОбъектаБДЛкс(ТипТаблицыБД) Тогда ТипСсылки = Тип(ирОбщий.ИмяТипаИзПолногоИмениМДЛкс(МетаданныеИсточника)); СписокСвойств = ирОбщий.ДопРеквизитыБСПОбъектаЛкс(Новый(ТипСсылки)); Для Каждого Свойство Из СписокСвойств Цикл #Если Сервер И Не Сервер Тогда Свойство = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.ПустаяСсылка(); #КонецЕсли ЗагружаемыйРеквизит = СопоставлениеКолонокБД.Добавить(); ЗагружаемыйРеквизит.ОписаниеТиповПриемника = Свойство.ТипЗначения; ЗагружаемыйРеквизит.ИмяКолонкиПриемника = Свойство.Имя; ЗагружаемыйРеквизит.СинонимКолонкиПриемника = Свойство.Наименование; ЗагружаемыйРеквизит.Принадлежность = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляГруппыИЭлемента; ЗагружаемыйРеквизит.ДопРеквизит = Свойство; ЗагружаемыйРеквизит.Подсказка = Свойство.Подсказка; ЗагружаемыйРеквизит.ДоступноИзменение = Истина; ВосстановитьИзменяемыеСвойстваСтрокиСопоставленияБД(ЗагружаемыйРеквизит, КопияСопоставления); КонецЦикла; КонецЕсли; СопоставлениеКолонокБД.Сортировать("СинонимКолонкиПриемника"); СопоставлениеКолонокБДЗаполнитьПоИменамСинонимам(Ложь); //ВыявитьНеуникальныеКлючи(); // Тут нельзя, т.к. ТаблицаЗначенийОтобранное может быть неактуальной КонецПроцедуры Процедура ВосстановитьИзменяемыеСвойстваСтрокиСопоставленияБД(Знач ЗагружаемыйРеквизит, Знач КопияСопоставления) СтараяСтрока = КопияСопоставления.Найти(ЗагружаемыйРеквизит.ИмяКолонкиПриемника, "ИмяКолонкиПриемника"); Если СтараяСтрока <> Неопределено Тогда ЗаполнитьЗначенияСвойств(ЗагружаемыйРеквизит, СтараяСтрока, "ИзИсточника, НеОчищать, ТолькоДляНовых, ПолеПоиска, Пометка, Значение, ИмяКолонкиИсточника"); СопоставитьКолонкуБД(ЗагружаемыйРеквизит, ТаблицаЗначений.Колонки.Найти(СтараяСтрока.ИмяКолонкиИсточника), Ложь); КонецЕсли; КонецПроцедуры Функция ВыявитьНеуникальныеКлючи(ТаблицаДляПроверки = Неопределено, выхСтрокаКлючаИсточника = "") Экспорт Если ТаблицаДляПроверки = Неопределено Тогда ТаблицаДляПроверки = ТаблицаЗначенийОтобранное; КонецЕсли; выхСтрокаКлючаИсточника = Новый Массив; Для Каждого СтрокаСопоставления Из СопоставлениеКолонокБД.НайтиСтроки(Новый Структура("ПолеПоиска", Истина)) Цикл Если Истина И ЗначениеЗаполнено(СтрокаСопоставления.ИмяКолонкиИсточника) И выхСтрокаКлючаИсточника.Найти(СтрокаСопоставления.ИмяКолонкиИсточника) = Неопределено Тогда выхСтрокаКлючаИсточника.Добавить(СтрокаСопоставления.ИмяКолонкиИсточника); КонецЕсли; КонецЦикла; выхСтрокаКлючаИсточника = ирОбщий.СтрСоединитьЛкс(выхСтрокаКлючаИсточника); НеуникальныеКлючи = ирОбщий.НеуникальныеКлючиТаблицыЛкс(ТаблицаДляПроверки, выхСтрокаКлючаИсточника); ЭтотОбъект.КоличествоНеуникально = НеуникальныеКлючи.Количество(); Возврат НеуникальныеКлючи; КонецФункции Процедура СопоставлениеКолонокБДЗаполнитьПоИменамСинонимам(РазрешитьМенятьИзИсточника = Истина, Знач СообщитьОПометке = Ложь) Экспорт СтруктураОтбораНесопоставленных = Новый Структура("СинонимКолонкиИсточника", ""); Для Этап = 1 По 2 Цикл Для Каждого Колонка Из ТаблицаЗначений.Колонки Цикл Если Колонка.Имя = мИмяКолонкиНомерСтроки Тогда Продолжить; КонецЕсли; СтрокаИмен = ""; СтрокиСопоставления = СопоставлениеКолонокБД.НайтиСтроки(СтруктураОтбораНесопоставленных); Для Каждого СтрокаСопоставления Из СтрокиСопоставления Цикл Если Не ирОбщий.ЛиОписаниеТипов1ВходитВОписаниеТипов2Лкс(Колонка.ТипЗначения, СтрокаСопоставления.ОписаниеТиповПриемника) Тогда Продолжить; КонецЕсли; Если Ложь Или (Истина // Сначала ищем пару по поглощению описания типов и именам И Этап = 1 И (Ложь Или ирОбщий.СтрокиРавныЛкс(СтрокаСопоставления.ИмяКолонкиПриемника, Колонка.Имя) Или ирОбщий.СтрокиРавныЛкс(СтрокаСопоставления.СинонимКолонкиПриемника, Колонка.Заголовок))) Или (Истина // Затем ищем пару по совпадению ссылочного моно типа И Этап = 2 И (Истина И Колонка.ТипЗначения.Типы().Количество() = 1 И ирОбщий.ЛиТипСсылкиБДЛкс(Колонка.ТипЗначения.Типы()[0]) И СтрокаСопоставления.ОписаниеТиповПриемника.Типы().Количество() = 1)) Тогда СопоставитьКолонкуБД(СтрокаСопоставления, Колонка, РазрешитьМенятьИзИсточника, СообщитьОПометке); СтрокаИмен = СтрокаИмен + ", " + СтрокаСопоставления.ИмяКолонкиПриемника; КонецЕсли; КонецЦикла; Если СтрокиСопоставления.Количество() > 0 Тогда СтрокаКолонки = КолонкиТЗ.Найти(Колонка.Имя, "ИмяКолонки"); Если СтрокаКолонки <> Неопределено Тогда СтрокаКолонки.КолонкиПриемника = СтрокаКолонки.КолонкиПриемника + СтрокаИмен; КонецЕсли; КонецЕсли; КонецЦикла; КонецЦикла; КонецПроцедуры Процедура ОбновитьКолонкиТаблицыБД(ОчиститьСуществующие = Истина, ДобавитьКолонкуРезультатаЗаписи = Истина) Экспорт Если ОчиститьСуществующие Тогда ТаблицаБД.Очистить(); ТаблицаБД.Колонки.Очистить(); КонецЕсли; ПроверитьДобавитьКолонкуИдентификатораСтроки(ТаблицаБД); Если ТаблицаБД.Колонки.Найти(мИмяКолонкиРезультатПоиска) = Неопределено Тогда ТаблицаБД.Колонки.Добавить(мИмяКолонкиРезультатПоиска, Новый ОписаниеТипов("Строка"), "<Результат поиска>"); КонецЕсли; Если ДобавитьКолонкуРезультатаЗаписи Тогда Если ТаблицаБД.Колонки.Найти(мИмяКолонкиРезультатЗаписи) = Неопределено Тогда ТаблицаБД.Колонки.Добавить(мИмяКолонкиРезультатЗаписи, Новый ОписаниеТипов("Строка"), "<Результат записи>"); КонецЕсли; Если ТаблицаБД.Колонки.Найти(мИмяКолонкиСообщенияОбработки) = Неопределено Тогда ТаблицаБД.Колонки.Добавить(мИмяКолонкиСообщенияОбработки, Новый ОписаниеТипов("Строка"), "<Сообщения>"); КонецЕсли; КонецЕсли; СтруктураКлючаОбъекта = ирОбщий.СтруктураКлючаТаблицыБДЛкс(ПолноеИмяТаблицы); Для каждого КлючИЗначение Из СтруктураКлючаОбъекта Цикл СтрокаСопоставленияБД = СопоставлениеКолонокБД.Найти(КлючИЗначение.Ключ, "ИмяКолонкиПриемника"); ТаблицаБД.Колонки.Добавить(СтрокаСопоставленияБД.ИмяКолонкиПриемника, СтрокаСопоставленияБД.ОписаниеТиповПриемника, СтрокаСопоставленияБД.СинонимКолонкиПриемника + " (ключ)"); КонецЦикла; КопияСопоставленияБД = СопоставлениеКолонокБД.Скопировать(); КопияСопоставленияБД.Сортировать("ПолеПоиска Убыв, Пометка Убыв"); Для каждого СтрокаСопоставленияБД Из КопияСопоставленияБД Цикл Если Ложь Или СтруктураКлючаОбъекта.Свойство(СтрокаСопоставленияБД.ИмяКолонкиПриемника) // Колонка уже добавлена выше Или (Истина И Не СтрокаСопоставленияБД.ПолеПоиска И Не СтрокаСопоставленияБД.Пометка) Тогда Продолжить; КонецЕсли; ЗаголовокКолонки = СтрокаСопоставленияБД.СинонимКолонкиПриемника; Если СтрокаСопоставленияБД.ПолеПоиска Тогда ЗаголовокКолонки = ЗаголовокКолонки + " (поиск)"; ИначеЕсли Не СтрокаСопоставленияБД.Пометка Тогда ЗаголовокКолонки = ЗаголовокКолонки + " (новая)"; КонецЕсли; ТаблицаБД.Колонки.Добавить(СтрокаСопоставленияБД.ИмяКолонкиПриемника, СтрокаСопоставленияБД.ОписаниеТиповПриемника, ЗаголовокКолонки); КонецЦикла; КонецПроцедуры Процедура ПроверитьДобавитьКолонкуИдентификатораСтроки(Таблица) Экспорт Если Таблица.Колонки.Найти(мИмяКолонкиНомерСтроки) = Неопределено Тогда Таблица.Колонки.Вставить(0, мИмяКолонкиНомерСтроки, Новый ОписаниеТипов("Число"), "<№>"); Счетчик = 1; Для Каждого СтрокаТаблицы Из Таблица Цикл СтрокаТаблицы[мИмяКолонкиНомерСтроки] = Счетчик; Счетчик = Счетчик + 1; КонецЦикла; КонецЕсли; КонецПроцедуры Процедура СопоставлениеКолонокТЗЗаполнить(УстановитьПометкуДляСопоставленных = Истина) Экспорт ОбновитьСопоставлениеКолонокТЗ(УстановитьПометкуДляСопоставленных); КолонкиТабличногоДокумента = ПолучитьКолонкиТабличногоДокумента(); Для Каждого КлючИЗначение Из КолонкиТабличногоДокумента Цикл Колонка = КлючИЗначение.Значение; СтруктураОтбора = Новый Структура("СинонимКолонкиИсточника", ""); СтрокиСопоставления = СопоставлениеКолонокТЗ.НайтиСтроки(СтруктураОтбора); КолонкаСопоставлена = Ложь; Для Каждого СтрокаСопоставления Из СтрокиСопоставления Цикл Если Ложь Или ирОбщий.СтрокиРавныЛкс(СтрокаСопоставления.СинонимКолонкиПриемника, Колонка.Заголовок) Или ирОбщий.СтрокиРавныЛкс(СтрокаСопоставления.ИмяКолонкиПриемника, Колонка.Заголовок) Тогда СопоставитьКолонкуТЗ(СтрокаСопоставления, Колонка); КолонкаСопоставлена = Истина; Прервать; КонецЕсли; КонецЦикла; Если КолонкаСопоставлена Тогда СтрокаКолонки = НесопоставленныеКолонкиТД.Найти(Колонка.Имя, "ИмяКолонки"); Если СтрокаКолонки <> Неопределено Тогда НесопоставленныеКолонкиТД.Удалить(СтрокаКолонки); КонецЕсли; КонецЕсли; КонецЦикла; КонецПроцедуры Процедура СопоставитьКолонкуБД(Знач СтрокаСопоставления, Знач КолонкаИсточника = Неопределено, Знач РазрешитьМенятьПометку = Истина, Знач СообщитьОПометке = Ложь) Экспорт Если Ложь Или РазрешитьМенятьПометку Или (Истина И КолонкаИсточника <> Неопределено И Не ЗначениеЗаполнено(СтрокаСопоставления.ИмяКолонкиИсточника)) Или (Истина И СтрокаСопоставления.ИзИсточника И КолонкаИсточника = Неопределено И ЗначениеЗаполнено(СтрокаСопоставления.ИмяКолонкиИсточника)) Тогда СтароеИзИсточника = СтрокаСопоставления.ИзИсточника; СтараяПометка = СтрокаСопоставления.Пометка; Если КолонкаИсточника <> Неопределено Тогда СтрокаСопоставления.ИзИсточника = Не СтараяПометка Или СтароеИзИсточника Или Не ЗначениеЗаполнено(СтрокаСопоставления.Значение); Иначе СтрокаСопоставления.ИзИсточника = Ложь; КонецЕсли; Если СтароеИзИсточника И Не СтрокаСопоставления.ИзИсточника Тогда СтрокаСопоставления.Пометка = Ложь; ИначеЕсли Не СтараяПометка И СтрокаСопоставления.ИзИсточника Тогда СтрокаСопоставления.Пометка = Истина; Если СообщитьОПометке Тогда ирОбщий.СообщитьЛкс(ирОбщий.СтрШаблонЛкс("Помечена для загрузки колонка БД ""%1""", СтрокаСопоставления.ИмяКолонкиПриемника)); КонецЕсли; КонецЕсли; КонецЕсли; Если КолонкаИсточника <> Неопределено Тогда СтрокаСопоставления.ИмяКолонкиИсточника = КолонкаИсточника.Имя; СтрокаСопоставления.СинонимКолонкиИсточника = КолонкаИсточника.Заголовок; СтрокаСопоставления.ОписаниеТиповИсточника = КолонкаИсточника.ТипЗначения; Иначе СтрокаСопоставления.ИмяКолонкиИсточника = ""; СтрокаСопоставления.СинонимКолонкиИсточника = ""; СтрокаСопоставления.ОписаниеТиповИсточника = Неопределено; КонецЕсли; КонецПроцедуры Процедура СопоставитьКолонкуТЗ(Знач СтрокаСопоставления, Знач Колонка = Неопределено, УстановитьДопСвойства = Истина) Экспорт Если Колонка <> Неопределено Тогда Если УстановитьДопСвойства Тогда СтрокаСопоставления.Пометка = Истина; Если СтрокаСопоставления.РежимКонвертации = "Устанавливать" Тогда СтрокаСопоставления.РежимКонвертации = "ИзИсточника"; КонецЕсли; КонецЕсли; СтрокаСопоставления.ИмяКолонкиИсточника = Колонка.Имя; СтрокаСопоставления.СинонимКолонкиИсточника = Колонка.Заголовок; СтрокаСопоставления.ПримерДанных = Колонка.ПримерДанных; Иначе Если СтрокаСопоставления.РежимКонвертации = "ИзИсточника" Тогда СтрокаСопоставления.РежимКонвертации = "Устанавливать"; КонецЕсли; СтрокаСопоставления.ИмяКолонкиИсточника = ""; СтрокаСопоставления.СинонимКолонкиИсточника = ""; СтрокаСопоставления.ПримерДанных = Неопределено; КонецЕсли; КонецПроцедуры Процедура ОчиститьСопоставлениеКолонокБД() Экспорт Для Каждого СтрокаКолонкиБД Из СопоставлениеКолонокБД Цикл СопоставитьКолонкуБД(СтрокаКолонкиБД); КонецЦикла; ОбновитьСопоставлениеКолонокБД(); КонецПроцедуры Процедура ОчиститьСопоставлениеКолонокТЗ() Экспорт СопоставлениеКолонокТЗ.ЗаполнитьЗначения(Неопределено, "ОписаниеТипов"); Для Каждого СтрокаКолонкиТЗ Из СопоставлениеКолонокТЗ Цикл СопоставитьКолонкуТЗ(СтрокаКолонкиТЗ); КонецЦикла; ОбновитьСопоставлениеКолонокТЗ(); КонецПроцедуры Процедура ОбновитьСопоставлениеКолонокБД() Экспорт Для Каждого СтрокаКолонкиБД Из СопоставлениеКолонокБД Цикл Колонка = ТаблицаЗначений.Колонки.Найти(СтрокаКолонкиБД.ИмяКолонкиИсточника); СопоставитьКолонкуБД(СтрокаКолонкиБД, Колонка, Ложь); КонецЦикла; КолонкиТЗ.Очистить(); Для Каждого Колонка Из ТаблицаЗначений.Колонки Цикл Если Ложь Или Колонка.Имя = мИмяКолонкиНомерСтроки Или ирОбщий.СтрКончаетсяНаЛкс(Колонка.Имя, мСуффиксСырыхДанных) Тогда Продолжить; КонецЕсли; СтрокаКолонки = КолонкиТЗ.Добавить(); СтрокаКолонки.ИмяКолонки = Колонка.Имя; СтрокаКолонки.СинонимКолонки = Колонка.Заголовок; СтрокаКолонки.ОписаниеТипов = Колонка.ТипЗначения; ИменаКолонокПриемника = СопоставлениеКолонокБД.Скопировать(Новый Структура("ИмяКолонкиИсточника", Колонка.Имя), "ИмяКолонкиПриемника").ВыгрузитьКолонку(0); СтрокаКолонки.КолонкиПриемника = ирОбщий.СтрСоединитьЛкс(ИменаКолонокПриемника); КонецЦикла; КолонкиТЗ.Сортировать("ИмяКолонки"); КонецПроцедуры Процедура ОбновитьСопоставлениеКолонокТЗ(УстановитьПометкуДляСопоставленных = Ложь, УстановитьПометкуДляНовых = Истина, ТолькоВыделенныеСтрокиТД = Ложь) Экспорт Для Каждого КолонкаТаблицы Из ТаблицаЗначений.Колонки Цикл Если Не ЗначениеЗаполнено(КолонкаТаблицы.Заголовок) Тогда КолонкаТаблицы.Заголовок = КолонкаТаблицы.Имя; КонецЕсли; КонецЦикла; КопияСопоставления = СопоставлениеКолонокТЗ.Скопировать(); СопоставлениеКолонокТЗ.Очистить(); КолонкиТабличногоДокумента = ПолучитьКолонкиТабличногоДокумента(, ТолькоВыделенныеСтрокиТД); Для Каждого Колонка Из ТаблицаЗначений.Колонки Цикл Если Ложь Или (Колонка.ТипЗначения.СодержитТип(Тип("ХранилищеЗначения")) И Колонка.ТипЗначения.Типы().Количество() = 1) Или (Колонка.ТипЗначения.СодержитТип(Тип("ТаблицаЗначений")) И Колонка.ТипЗначения.Типы().Количество() = 1) Или ирОбщий.СтрокиРавныЛкс(Колонка.Имя, мИмяКолонкиНомерСтроки) Или ирОбщий.СтрКончаетсяНаЛкс(Колонка.Имя, мСуффиксСырыхДанных) Тогда Продолжить; КонецЕсли; ЗагружаемыйРеквизит = СопоставлениеКолонокТЗ.Добавить(); ЗагружаемыйРеквизит.ИмяКолонкиПриемника = Колонка.Имя; ЗагружаемыйРеквизит.Пометка = УстановитьПометкуДляНовых; ЗагружаемыйРеквизит.СинонимКолонкиПриемника = Колонка.Заголовок; ЗагружаемыйРеквизит.ДоступноеОписаниеТипов = Колонка.ТипЗначения; ЗагружаемыйРеквизит.ОписаниеТипов = Колонка.ТипЗначения; СписокВыбора = ПолучитьСписокИменПредставлений(ЗагружаемыйРеквизит); ЗагружаемыйРеквизит.ИскатьПо = ?(СписокВыбора.Количество() = 0, "",СписокВыбора[0].Значение); СписокВыбора = СписокСвязейКолонкиПоВладельцу(ЗагружаемыйРеквизит); ЗагружаемыйРеквизит.СвязьПоВладельцу = ?(СписокВыбора.Количество() = 0, "", СписокВыбора[0].Значение); //СписокВыбора = СписокСвязейКолонкиПоТипу(ЗагружаемыйРеквизит); //Если СписокВыбора.Количество() = 0 Тогда // ЗагружаемыйРеквизит.СвязьПоТипу = ""; // ЗагружаемыйРеквизит.ЭлементСвязиПоТипу = 0; //Иначе // ЗагружаемыйРеквизит.СвязьПоТипу = СписокВыбора[0].Значение; // Если Найти(ЗагружаемыйРеквизит.ИмяКолонкиПриемника, "3") <> 0 Тогда // ЗагружаемыйРеквизит.ЭлементСвязиПоТипу = 3; // ИначеЕсли Найти(ЗагружаемыйРеквизит.ИмяКолонкиПриемника, "2") <> 0 Тогда // ЗагружаемыйРеквизит.ЭлементСвязиПоТипу = 2; // Иначе // ЗагружаемыйРеквизит.ЭлементСвязиПоТипу = 1; // КонецЕсли; //КонецЕсли; ЗагружаемыйРеквизит.Значение = ЗагружаемыйРеквизит.ОписаниеТипов.ПривестиЗначение(Неопределено); ЗагружаемыйРеквизит.РежимКонвертации = "ИзИсточника"; СтараяСтрока = КопияСопоставления.Найти(ЗагружаемыйРеквизит.ИмяКолонкиПриемника, "ИмяКолонкиПриемника"); Если СтараяСтрока <> Неопределено Тогда ЗаполнитьЗначенияСвойств(ЗагружаемыйРеквизит, СтараяСтрока,, "СинонимКолонкиПриемника, ОписаниеТипов, ДоступноеОписаниеТипов"); ПересечениеТипов = ирОбщий.ПересечьОписанияТиповЛкс(СтараяСтрока.ОписаниеТипов, ЗагружаемыйРеквизит.ОписаниеТипов,, 2); #Если Сервер И Не Сервер Тогда ПересечениеТипов = Новый ОписаниеТипов; #КонецЕсли КоличествоТипов = ПересечениеТипов.Типы().Количество(); Если КоличествоТипов > 0 Тогда ЗагружаемыйРеквизит.ОписаниеТипов = ПересечениеТипов; Корреспонденция = Лев(Прав(Колонка.Имя, 3), 2); Если Истина И Не ЗначениеЗаполнено(ЗагружаемыйРеквизит.СвязьПоТипу) И КоличествоТипов > 1 И ирОбщий.ЛиЦифраЛкс(Прав(Колонка.Имя, 1)) И (Ложь Или ирОбщий.СтрокиРавныЛкс(ирОбщий.ПеревестиСтроку("Кт"), Корреспонденция) Или ирОбщий.СтрокиРавныЛкс(ирОбщий.ПеревестиСтроку("Дт"), Корреспонденция)) Тогда Для Каждого КолонкаСчета Из ТаблицаЗначений.Колонки Цикл Если Не ирОбщий.СтрокиРавныЛкс(Корреспонденция, Прав(КолонкаСчета.Имя, 2)) Тогда Продолжить; КонецЕсли; ТипыСчета = КолонкаСчета.ТипЗначения.Типы(); Если Истина И ТипыСчета.Количество() > 0 И ПланыСчетов.ТипВсеСсылки().СодержитТип(ТипыСчета[0]) И ирОбщий.ЛиОписаниеТипов1ВходитВОписаниеТипов2Лкс(ЗагружаемыйРеквизит.ОписаниеТипов, Метаданные.НайтиПоТипу(ТипыСчета[0]).ВидыСубконто.Тип) Тогда ЗагружаемыйРеквизит.СвязьПоТипу = КолонкаСчета.Имя; ЗагружаемыйРеквизит.ЭлементСвязиПоТипу = Число(Прав(Колонка.Имя, 1)); Прервать; КонецЕсли; КонецЦикла; КонецЕсли; КонецЕсли; Если ЗагружаемыйРеквизит.РежимКонвертации = "ИзИсточника" Тогда СопоставитьКолонкуТЗ(ЗагружаемыйРеквизит, КолонкиТабличногоДокумента[СтараяСтрока.ИмяКолонкиИсточника], УстановитьПометкуДляСопоставленных); КонецЕсли; КонецЕсли; КонецЦикла; СопоставлениеКолонокТЗ.Сортировать("СинонимКолонкиПриемника"); // Восстановим настроенный пользователем порядок строк Счетчик = 0; Для Каждого СтараяСтрока Из КопияСопоставления Цикл НоваяСтрока = СопоставлениеКолонокТЗ.Найти(СтараяСтрока.ИмяКолонкиПриемника, "ИмяКолонкиПриемника"); Если НоваяСтрока = Неопределено Тогда Продолжить; КонецЕсли; СопоставлениеКолонокТЗ.Сдвинуть(НоваяСтрока, Счетчик - СопоставлениеКолонокТЗ.Индекс(НоваяСтрока)); Счетчик = Счетчик + 1; КонецЦикла; //КолонкиТабличногоДокумента = ПолучитьКолонкиТабличногоДокумента(); Для Каждого СтрокаКолонкиТЗ Из СопоставлениеКолонокТЗ Цикл //Если Не СтрокаКолонкиТЗ.РежимКонвертации = "ИзИсточника" Тогда // Продолжить; //КонецЕсли; Если ЗначениеЗаполнено(СтрокаКолонкиТЗ.ИмяКолонкиИсточника) Тогда Колонка = КолонкиТабличногоДокумента[СтрокаКолонкиТЗ.ИмяКолонкиИсточника]; СопоставитьКолонкуТЗ(СтрокаКолонкиТЗ, Колонка, УстановитьПометкуДляСопоставленных); КонецЕсли; КонецЦикла; ОбновитьНесопоставлениеКолонкиТД(ТолькоВыделенныеСтрокиТД); ОбновитьОшибкиКонвертацииПриИзмененииСоставаКолонокТЗ(); КонецПроцедуры Процедура ОбновитьОшибкиКонвертацииПриИзмененииСоставаКолонокТЗ() Экспорт УдаляемыеСтроки = Новый Массив; Для Каждого СтрокаОшибки Из ОшибкиКонвертации Цикл СтрокаСопоставления = СопоставлениеКолонокТЗ.Найти(СтрокаОшибки.КолонкаИсточника, "ИмяКолонкиИсточника"); Если СтрокаСопоставления <> Неопределено Тогда СтрокаОшибки.КолонкаПриемника = СтрокаСопоставления.ИмяКолонкиПриемника; Иначе УдаляемыеСтроки.Добавить(СтрокаОшибки); КонецЕсли; КонецЦикла; Для Каждого Строка Из УдаляемыеСтроки Цикл ОшибкиКонвертации.Удалить(Строка); КонецЦикла; КонецПроцедуры Процедура ОбновитьНесопоставлениеКолонкиТД(Знач ТолькоВыделенныеСтрокиТД = Ложь) Экспорт КолонкиТабличногоДокумента = ПолучитьКолонкиТабличногоДокумента(, ТолькоВыделенныеСтрокиТД); НесопоставленныеКолонкиТД.Очистить(); Для Каждого КлючИЗначение Из КолонкиТабличногоДокумента Цикл Колонка = КлючИЗначение.Значение; Если СопоставлениеКолонокТЗ.Найти(Колонка.Имя, "ИмяКолонкиИсточника") = Неопределено Тогда СтрокаКолонки = НесопоставленныеКолонкиТД.Добавить(); СтрокаКолонки.ИмяКолонки = Колонка.Имя; СтрокаКолонки.СинонимКолонки = Колонка.Заголовок; СтрокаКолонки.ПримерДанных = Колонка.ПримерДанных; КонецЕсли; КонецЦикла; НесопоставленныеКолонкиТД.Сортировать("СинонимКолонки"); КонецПроцедуры //ирПортативный лФайл = Новый Файл(ИспользуемоеИмяФайла); //ирПортативный ПолноеИмяФайлаБазовогоМодуля = Лев(лФайл.Путь, СтрДлина(лФайл.Путь) - СтрДлина("Модули\")) + "ирПортативный.epf"; //ирПортативный #Если Клиент Тогда //ирПортативный Контейнер = Новый Структура(); //ирПортативный Оповестить("ирПолучитьБазовуюФорму", Контейнер); //ирПортативный Если Не Контейнер.Свойство("ирПортативный", ирПортативный) Тогда //ирПортативный ирПортативный = ВнешниеОбработки.ПолучитьФорму(ПолноеИмяФайлаБазовогоМодуля); //ирПортативный ирПортативный.Открыть(); //ирПортативный КонецЕсли; //ирПортативный #Иначе //ирПортативный ирПортативный = ВнешниеОбработки.Создать(ПолноеИмяФайлаБазовогоМодуля, Ложь); // Это будет второй экземпляр объекта //ирПортативный #КонецЕсли //ирПортативный ирОбщий = ирПортативный.ПолучитьОбщийМодульЛкс("ирОбщий"); //ирПортативный ирКэш = ирПортативный.ПолучитьОбщийМодульЛкс("ирКэш"); //ирПортативный ирСервер = ирПортативный.ПолучитьОбщийМодульЛкс("ирСервер"); //ирПортативный ирПривилегированный = ирПортативный.ПолучитьОбщийМодульЛкс("ирПривилегированный"); мПлатформа = ирКэш.Получить(); мИмяКолонкиНомерСтроки = ирОбщий.ИмяКолонкиВнутреннегоИДСтрокиЛкс(); мИмяКолонкиРезультатПоиска = "_РезультатПоиска" + ирОбщий.СуффиксСлужебногоСвойстваЛкс(); мИмяКолонкиРезультатЗаписи = "_РезультатЗаписи" + ирОбщий.СуффиксСлужебногоСвойстваЛкс(); мИмяКолонкиСообщенияОбработки = "_Сообщения" + ирОбщий.СуффиксСлужебногоСвойстваЛкс(); мСуффиксСырыхДанных = "_Сырое" + ирОбщий.СуффиксСлужебногоСвойстваЛкс(); мЭтоСсылочныйОбъект = Ложь; ВыводитьОшибкиКонвертацииСразу = Истина; ВыводитьОшибкаЗагрузкиСразу = Истина; ДобавлятьСтрокиБД = Истина; ОбновлятьСтрокиБД = Истина; ОтбиратьСразу = Истина; СвязиИПараметрыВыбора = Истина; ЭтотОбъект.КоличествоПотоков = 1; ЭтотОбъект.КоличествоОбъектовВПорции = 10; ЭтотОбъект.ВыполнятьЗагрузкуНаСервере = ирОбщий.РежимОбъектыНаСервереПоУмолчаниюЛкс(Ложь); ЭтотОбъект.ВыполнятьКонвертациюНаСервере = Ложь; ПримитивныеТипы = Новый Структура; ПримитивныеТипы.Вставить("Число", Тип("Число")); ПримитивныеТипы.Вставить("Дата", Тип("Дата")); ПримитивныеТипы.Вставить("Булево", Тип("Булево")); ПримитивныеТипы.Вставить("Строка", Тип("Строка")); мАлгоритмКонвертацииЗначенияПараметры = ирОбщий.ТаблицаЗначенийИзТабличногоДокументаЛкс(ПолучитьМакет("АлгоритмКонвертацииЗначения"),,,, Истина); мАлгоритмКонвертацииЗначенияПараметры.Колонки.Добавить("ТаблицаСтруктурТипов");