//ирПортативный Перем ирПортативный Экспорт; //ирПортативный Перем ирОбщий Экспорт; //ирПортативный Перем ирСервер Экспорт; //ирПортативный Перем ирКэш Экспорт; //ирПортативный Перем ирПривилегированный Экспорт; // Структура примитивных типов (Булево, Дата, Строка, Число) Перем ПримитивныеТипы; Перем мИмяКолонкиНомерСтроки Экспорт; Перем мИмяКолонкиРезультатПоиска Экспорт; Перем мИмяКолонкиРезультатЗаписи Экспорт; Перем мИмяКолонкиСообщенияОбработки Экспорт; Перем мАлгоритмКонвертацииЗначенияПараметры Экспорт; Перем мЭтоСсылочныйОбъект Экспорт; Перем мПлатформа Экспорт; Перем мКоличествоУспешно Экспорт; Перем мКоличествоНеуспешно Экспорт; Перем мТекущееПолноеИмяТаблицы Экспорт; Перем мКонсольЗапросов Экспорт; Перем мДополнениеЗапросом Экспорт; Перем мСуффиксСырыхДанных Экспорт; // Выводит сообщение об ошибке и выставляет параметр Отказ в "Истина". // В случае работы на клиенте или на сервере выводит в окно сообщений, // в случае внешнего соединения вызывает исключение. // // Параметры: // ТекстСообщения - строка, текст сообщения. // Отказ - булево, признак отказа (необязательный). // Функция ПолучитьПричинуОшибки(ТекстСообщения, Отказ = Ложь, Заголовок = "") Экспорт НачалоСлужебногоСообщения = Найти(ТекстСообщения, "{"); ОкончаниеСлужебногоСообщения = Найти(ТекстСообщения, "}:"); Если ОкончаниеСлужебногоСообщения > 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; НачальнаяСтрока = СтруктураПозицийТД.НомерСтрокиДанных; КонечнаяСтрока = ТабличныйДокумент.ВысотаТаблицы; Если ТолькоВыделенныеСтрокиТД Тогда Если ТабличныйДокумент.ТекущаяОбласть.Верх <= КонечнаяСтрока Тогда НачальнаяСтрока = Макс(НачальнаяСтрока, ТабличныйДокумент.ТекущаяОбласть.Верх); КонецЕсли; Если ТабличныйДокумент.ТекущаяОбласть.Низ >= НачальнаяСтрока Тогда КонечнаяСтрока = Мин(КонечнаяСтрока, ТабличныйДокумент.ТекущаяОбласть.Низ); КонецЕсли; КонецЕсли; КоличествоЭлементов = КонечнаяСтрока - НачальнаяСтрока + 1; Если КоличествоЭлементов <= 0 Тогда ирОбщий.СообщитьЛкс("Нет данных для конвертации. Задайте ""Начало данных"" на странице ""Табличный документ"""); Возврат Ложь; КонецЕсли; СоответствиеКолонок = ПолучитьКолонкиТабличногоДокумента(СтруктураПозицийТД); ТаблицаЗначений.Очистить(); Если ДобавлятьСырыеДанныеВТЗ Тогда Для каждого СтрокаСопоставления Из СопоставлениеКолонокТЗ.НайтиСтроки(Новый Структура("Пометка", Истина)) Цикл Если СтрокаСопоставления.РежимКонвертации = "Устанавливать" Тогда Продолжить; КонецЕсли; ИмяСыройКолонки = СтрокаСопоставления.ИмяКолонкиПриемника + мСуффиксСырыхДанных; Если ТаблицаЗначений.Колонки.Найти(ИмяСыройКолонки) = Неопределено Тогда ЗаголовокКолонки = ТаблицаЗначений.Колонки[СтрЗаменить(ИмяСыройКолонки, мСуффиксСырыхДанных, "")].Заголовок + ". Сырое"; ТаблицаЗначений.Колонки.Добавить(ИмяСыройКолонки, Новый ОписаниеТипов("Строка"), ЗаголовокКолонки); КонецЕсли; КонецЦикла; КонецЕсли; Если ЭтаФорма <> Неопределено Тогда ЭтаФорма.ТаблицаЗначенийОтобранное = ТаблицаЗначений; ЭтаФорма.ОбновитьКолонкиТабличногоПоляТаблицыЗначений(); ЭтаФорма.ТаблицаЗначенийОтобранное = ТаблицаЗначений; ЭтаФорма.ТекущийЭлемент = ЭтаФорма.ЭлементыФормы.ТаблицаЗначений; ЭтаФорма.ЭлементыФормы.ТаблицаЗначений.ОбновитьСтроки(); КонецЕсли; Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(КоличествоЭлементов, "Конвертация ТД => ТЗ"); Для НомерСтроки = НачальнаяСтрока По КонечнаяСтрока Цикл Если ирОбщий.ОбработатьИндикаторЛкс(Индикатор) Тогда Если Истина И ЭтаФорма <> Неопределено И ТаблицаЗначений.Количество() < 40 Тогда ЭтаФорма.ЭлементыФормы.ТаблицаЗначений.ОбновитьСтроки(); КонецЕсли; КонецЕсли; ТекущаяСтрока = КонтрольЗаполненияСтроки(ТабличныйДокумент, НомерСтроки, , КоличествоОшибокКонвертации, КэшПоиска); #Если Сервер И Не Сервер Тогда ТекущаяСтрока = Новый Структура; #КонецЕсли СтрокаДанных = ТаблицаЗначений.Добавить(); СтрокаДанных[мИмяКолонкиНомерСтроки] = НомерСтроки; Для каждого КлючИЗначение Из ТекущаяСтрока Цикл СтрокаДанных[КлючИЗначение.Ключ] = КлючИЗначение.Значение; КонецЦикла; КонецЦикла; ирОбщий.ОсвободитьИндикаторПроцессаЛкс(, Истина); СообщитьИтогиКонвертации(КоличествоОшибокКонвертации); Возврат Истина; КонецФункции // Функция интерактивно предлагает выбрать значение в текущей ячейке табличного документа // // Параметры: // ТабличныйДокумент - ТабличныйДокумент, в текущей ячейке которого необходимо выбрать значение // // Возвращаемое значение: // Истина, если значение выбрано, Ложь - иначе // Процедура ВыбратьЗначениеВЯчейке() Экспорт ОчиститьСообщения(); ТекущаяОбласть = ТабличныйДокумент.ТекущаяОбласть; Если ТекущаяОбласть.Верх <> ТекущаяОбласть.Низ Или ТекущаяОбласть.Лево <> ТекущаяОбласть.Право Тогда Предупреждение("Для непосредственного выбора значения необходимо выбирать только одну ячейку"); Возврат; КонецЕсли; ТекущаяКолонка = ПолучитьКолонку(ТекущаяОбласть); Если ТекущаяКолонка = Неопределено Тогда Предупреждение("Значение данной колонки не выбирается"); Возврат; КонецЕсли; ТекущаяСтрока = КонтрольЗаполненияСтроки(ТабличныйДокумент, ТекущаяОбласть.Верх); Значение = ТекущаяОбласть.Расшифровка; СвязьПоТипу = Неопределено; Если Не ПустаяСтрока(ТекущаяКолонка.СвязьПоТипу) Тогда Если ТипЗНЧ(ТекущаяКолонка.СвязьПоТипу) = Тип("Строка") Тогда ТекущаяСтрока.Свойство(ТекущаяКолонка.СвязьПоТипу,СвязьПоТипу); Иначе СвязьПоТипу = ТекущаяКолонка.СвязьПоТипу; КонецЕсли; КонецЕсли; СвязьПоВладельцу = Неопределено; Если Не ПустаяСтрока(ТекущаяКолонка.СвязьПоВладельцу) Тогда Если ТипЗНЧ(ТекущаяКолонка.СвязьПоВладельцу) = Тип("Строка") Тогда ТекущаяСтрока.Свойство(ТекущаяКолонка.СвязьПоВладельцу,СвязьПоВладельцу); Иначе СвязьПоВладельцу = ТекущаяКолонка.СвязьПоВладельцу; КонецЕсли; КонецЕсли; ЭлементСвязиПоТипу = ?(ТекущаяКолонка.ЭлементСвязиПоТипу = 0,1,ТекущаяКолонка.ЭлементСвязиПоТипу); Если мВыбратьЗначение(Значение, ТекущаяКолонка.ОписаниеТипов, СвязьПоТипу, ЭлементСвязиПоТипу, СвязьПоВладельцу, ТекущаяКолонка.ИмяКолонкиПриемника = "Родитель") Тогда ТекущаяОбласть.Расшифровка = Значение; Если ПустаяСтрока(ТекущаяКолонка.ИскатьПо) Тогда ТекущаяОбласть.Текст = Строка(Значение); Иначе ТекущаяОбласть.Текст = Строка(Значение[ТекущаяКолонка.ИскатьПо]); КонецЕсли; ОчиститьСообщения(); КонтрольЗаполненияСтроки(ТабличныйДокумент, ТекущаяОбласть.Верх); КонецЕсли; КонецПроцедуры // () // Процедура обновляет содержимое табличного документа, в соответствии с таблицей загружаемых реквизитов // // Параметры: // ТабличныйДокумент - ТабличныйДокумент, который необходимо обновить // БезВопросов - булево, если Ложь, спрашивать об очистке табличного документа, если он не пустой, Истина - иначе // Процедура ОбновитьДанныеТабличногоДокумента(БезВопросов = Ложь) Экспорт #Если Сервер И Не Сервер Тогда ТабличныйДокумент = Новый ТабличныйДокумент; #КонецЕсли Если ТабличныйДокумент.ВысотаТаблицы > 1 И Не БезВопросов Тогда Результат = Вопрос("Табличный документ содержит данные. Очистить?", РежимДиалогаВопрос.ДаНетОтмена, , КодВозвратаДиалога.Нет); Если Результат = КодВозвратаДиалога.Да Тогда ТабличныйДокумент.Очистить(); ИначеЕсли Результат = КодВозвратаДиалога.Отмена Тогда Возврат; Иначе СтруктураПозицийТД = СтруктураПозицийТД(Истина); Для К = 1 По ТабличныйДокумент.ШиринаТаблицы Цикл ТабличныйДокумент.Область(СтруктураПозицийТД.НомерСтрокиЗаголовков, К).Текст = ""; КонецЦикла; КонецЕсли; Иначе ТабличныйДокумент.Очистить(); КонецЕсли; Если ТабличныйДокумент.ВысотаТаблицы = 0 Тогда СтрокаЗаголовковТД = 0; ПерваяСтрокаДанныхТД = 0; КонецЕсли; //СформироватьСтруктуруКолонок(); СформироватьШапкуТабличногоДокумента(СтруктураПозицийТД); КонецПроцедуры #КонецЕсли // Функция возвращает метаданные источника данных // // Параметры: // нет // // Возвращаемое значение: // Объект метаданных // Функция МетаданныеТаблицыБД() Экспорт Результат = ирОбщий.ОбъектМДПоПолномуИмениТаблицыБДЛкс(ПолноеИмяТаблицы); Возврат Результат; КонецФункции // Функция возвращает значение структуры "Колонки" по области табличного документа, // содержащее описание свойств колонки // // Параметры: // область - область табличного документа // // Возвращаемое значение: // значение структуры "Колонки" // Функция ПолучитьКолонку(Область) Для каждого СтрокаСопоставления Из СопоставлениеКолонокТЗ Цикл Если "" + Область.Лево = СтрокаСопоставления.ИмяКолонкиИсточника Тогда Возврат СтрокаСопоставления; КонецЕсли; КонецЦикла; Возврат Неопределено; КонецФункции // () // Процедура формирует шапку табличного документа, в соответствии с таблицей загружаемых реквизитов // // Параметры: // ТабличныйДокумент - ТабличныйДокумент, у которого необходимо сформировать шапку // Процедура СформироватьШапкуТабличногоДокумента(СтруктураПозицийТД = Неопределено) Экспорт Линия = Новый Линия(ТипЛинииЯчейкиТабличногоДокумента.Сплошная, 1); Таблица = СопоставлениеКолонокТЗ.Скопировать(); Таблица.Сортировать("ИмяКолонкиИсточника"); Для каждого СтрокаСопоставления Из СопоставлениеКолонокТЗ Цикл НомерКолонки = СтрокаСопоставления.ИмяКолонкиИсточника; Если Не СтрокаСопоставления.Пометка Тогда Продолжить; КонецЕсли; Если Не ЗначениеЗаполнено(НомерКолонки) Тогда Для Счетчик = 1 По СопоставлениеКолонокТЗ.Количество() Цикл Если СопоставлениеКолонокТЗ.Найти("" + Счетчик, "ИмяКолонкиИсточника") = Неопределено Тогда НомерКолонки = Счетчик; Прервать; КонецЕсли; КонецЦикла; Если Не ЗначениеЗаполнено(НомерКолонки) Тогда Продолжить; КонецЕсли; ОписаниеКолонки = Новый Структура("Имя, Заголовок, ПримерДанных", "" + НомерКолонки, СтрокаСопоставления.СинонимКолонкиПриемника, ""); СопоставитьКолонкуТЗ(СтрокаСопоставления, ОписаниеКолонки); КонецЕсли; Если СтрокаСопоставления.ШиринаКолонки = 0 Тогда ШиринаКолонки = 40; Если СтрокаСопоставления.ОписаниеТипов.Типы().Количество() = 1 Тогда ПервыйТип = СтрокаСопоставления.ОписаниеТипов.Типы()[0]; Если ПервыйТип = Тип("Строка") Тогда Если СтрокаСопоставления.ОписаниеТипов.КвалификаторыСтроки.Длина = 0 Тогда ШиринаКолонки = 80; Иначе ШиринаКолонки = Мин(Макс(СтрокаСопоставления.ОписаниеТипов.КвалификаторыСтроки.Длина,10),80); КонецЕсли; ИначеЕсли ПервыйТип = Тип("Число") Тогда ШиринаКолонки = Макс(СтрокаСопоставления.ОписаниеТипов.КвалификаторыЧисла.Разрядность,10); ИначеЕсли ПервыйТип = Тип("Булево") Тогда ШиринаКолонки = 10; КонецЕсли; КонецЕсли; Иначе ШиринаКолонки = СтрокаСопоставления.ШиринаКолонки; КонецЕсли; Если СтруктураПозицийТД = Неопределено Тогда СтруктураПозицийТД = СтруктураПозицийТД(Истина); КонецЕсли; Область = ТабличныйДокумент.Область(СтруктураПозицийТД.НомерСтрокиЗаголовков, НомерКолонки); БылТекст = Не ПустаяСтрока(Область.Текст); Область.Текст = ?(БылТекст, Область.Текст + Символы.ПС,"") + СтрокаСопоставления.СинонимКолонкиПриемника; Область.Расшифровка = СтрокаСопоставления.ИмяКолонкиПриемника; Область.ЦветФона = ЦветаСтиля.ЦветФонаФормы; Область.Обвести(Линия, Линия, Линия, Линия); ОбластьКолонки = ТабличныйДокумент.Область("C"+НомерКолонки); ОбластьКолонки.ШиринаКолонки = ?(БылТекст, Макс(ОбластьКолонки.ШиринаКолонки,ШиринаКолонки),ШиринаКолонки); КонецЦикла; //ОбновитьКолонкиТаблицыЗначений(, Ложь); КонецПроцедуры // Параметры: // ИзБД - Булево - Истина - из БД, иначе из табличного документа // Процедура ОбновитьКолонкиТаблицыЗначений(ОчиститьСуществующие = Ложь, ИзБД = Истина) Экспорт Если ОчиститьСуществующие Тогда ТаблицаЗначений.Очистить(); ТаблицаЗначений.Колонки.Очистить(); ЭтотОбъект.ТаблицаЗначенийИспользоватьОтбор = Ложь; КонецЕсли; ПроверитьДобавитьКолонкуИдентификатораСтроки(ТаблицаЗначений); Если ИзБД Тогда Если ЗначениеЗаполнено(ПолноеИмяТаблицы) Тогда Если Истина И СопоставлениеКолонокБД.НайтиСтроки(Новый Структура("Пометка", Истина)).Количество() = 0 И СопоставлениеКолонокБД.НайтиСтроки(Новый Структура("ПолеПоиска", Истина)).Количество() = 0 Тогда СопоставлениеКолонокБД.ЗаполнитьЗначения(Истина, "Пометка"); КонецЕсли; Для каждого СтрокаСопоставленияБД Из СопоставлениеКолонокБД Цикл Если Ложь Или ТаблицаЗначений.Колонки.Найти(СтрокаСопоставленияБД.ИмяКолонкиПриемника) <> Неопределено Или (Не СтрокаСопоставленияБД.Пометка И Не СтрокаСопоставленияБД.ПолеПоиска) Тогда Продолжить; КонецЕсли; ТаблицаЗначений.Колонки.Добавить(СтрокаСопоставленияБД.ИмяКолонкиПриемника, СтрокаСопоставленияБД.ОписаниеТиповПриемника, СтрокаСопоставленияБД.СинонимКолонкиПриемника); КонецЦикла; КонецЕсли; Иначе СтруктураПозицийТД = СтруктураПозицийТД(); ИндикаторКолонок = ирОбщий.ПолучитьИндикаторПроцессаЛкс(ТабличныйДокумент.ШиринаТаблицы, "Анализ документа"); Для НомерКолонки = 1 По ТабличныйДокумент.ШиринаТаблицы Цикл ирОбщий.ОбработатьИндикаторЛкс(ИндикаторКолонок); СинонимКолонки = ""; Если ЗначениеЗаполнено(СтруктураПозицийТД.НомерСтрокиЗаголовков) Тогда СинонимКолонки = ТабличныйДокумент.Область(СтруктураПозицийТД.НомерСтрокиЗаголовков, НомерКолонки).Текст; КонецЕсли; Если Не ЗначениеЗаполнено(СинонимКолонки) Тогда СинонимКолонки = "Колонка " + НомерКолонки; КонецЕсли; ИмяКолонки = ирОбщий.ИдентификаторИзПредставленияЛкс(СинонимКолонки); Если ТаблицаЗначений.Колонки.Найти(ИмяКолонки) <> Неопределено Тогда Продолжить; КонецЕсли; ШиринаКолонки = ТабличныйДокумент.Область(СтруктураПозицийТД.НомерСтрокиДанных, НомерКолонки).ШиринаКолонки; //Если ЛиВтораяСтрокаСодержитТипыЗначений Тогда Если Ложь Тогда ИменаТипов = ТабличныйДокумент.Область(2, НомерКолонки).Текст; Иначе ИменаТипов = Новый Массив; МаксДлинаСтроки = 0; УспешныеТипы = Новый Соответствие; НеуспешныеТипы = Новый Соответствие; Для Каждого ПримитивныйТип Из ПримитивныеТипы Цикл ПримитивныйТип = ПримитивныйТип.Ключ; УспешныеТипы[ПримитивныйТип] = 0; НеуспешныеТипы[ПримитивныйТип] = 0; КонецЦикла; Для НомерСтроки = СтруктураПозицийТД.НомерСтрокиДанных По Мин(ТабличныйДокумент.ВысотаТаблицы, 10000 / ТабличныйДокумент.ШиринаТаблицы) Цикл #Если Клиент Тогда ОбработкаПрерыванияПользователя(); #КонецЕсли ОбластьЯчейки = ТабличныйДокумент.Область(НомерСтроки, НомерКолонки); Если ОбластьЯчейки.Лево <> НомерКолонки Тогда // Не левая ячейка объединенной горизонтально области Продолжить; КонецЕсли; Расшифровка = ОбластьЯчейки.Расшифровка; Если Истина И Расшифровка <> Неопределено И ТипЗнч(Расшифровка) <> Тип("ИдентификаторРасшифровкиКомпоновкиДанных") Тогда ИменаТипов.Добавить(ТипЗнч(Расшифровка)); Иначе ТекстЯчейки = ОбластьЯчейки.Текст; Если ЗначениеЗаполнено(ТекстЯчейки) Тогда Для Каждого ПримитивныйТип Из ПримитивныеТипы Цикл ПримитивныйТип = ПримитивныйТип.Ключ; Если ПримитивныйТип = "Строка" Тогда Продолжить; ИначеЕсли ПримитивныйТип = "Дата" Тогда ОшибкиКонвертации = ""; РезультатКонвертации = ирОбщий.СтрокаВДатуЛкс(ТекстЯчейки,, ОшибкиКонвертации); Если ЗначениеЗаполнено(ОшибкиКонвертации) Тогда РезультатКонвертации = Неопределено; КонецЕсли; Иначе Попытка РезультатКонвертации = Вычислить(ПримитивныйТип + "(ТекстЯчейки)"); Исключение РезультатКонвертации = Неопределено; КонецПопытки; КонецЕсли; Если Истина И РезультатКонвертации <> Неопределено И Не (Истина И ПримитивныйТип = "Число" И Лев(ТекстЯчейки, 1) = "0" И СтрДлина(ТекстЯчейки) > 1 И Найти(ТекстЯчейки, ".") > 2) Тогда УспешныеТипы[ПримитивныйТип] = УспешныеТипы[ПримитивныйТип] + 1; Иначе НеуспешныеТипы[ПримитивныйТип] = НеуспешныеТипы[ПримитивныйТип] + 1; КонецЕсли; КонецЦикла; КонецЕсли; КонецЕсли; Если МаксДлинаСтроки < СтрДлина(ОбластьЯчейки.Текст) Тогда МаксДлинаСтроки = СтрДлина(ОбластьЯчейки.Текст); КонецЕсли; КонецЦикла; Для Каждого ПримитивныйТип Из ПримитивныеТипы Цикл ПримитивныйТип = ПримитивныйТип.Ключ; Если УспешныеТипы[ПримитивныйТип] > 0 И НеуспешныеТипы[ПримитивныйТип] <= 1 Тогда // 1 неуспешный допускается, т.к. иногда в анализируемую область попадает подвал ИменаТипов.Добавить(Тип(ПримитивныйТип)); Прервать; КонецЕсли; КонецЦикла; Если ИменаТипов.Количество() = 0 Тогда ИменаТипов = "Строка"; КонецЕсли; КонецЕсли; ТаблицаЗначений.Колонки.Добавить(ИмяКолонки, Новый ОписаниеТипов(ИменаТипов,,,, Новый КвалификаторыСтроки(МаксДлинаСтроки)), СинонимКолонки, ШиринаКолонки); КонецЦикла; ирОбщий.ОсвободитьИндикаторПроцессаЛкс(); КонецЕсли; КонецПроцедуры Функция СтруктураПозицийТД(ОбязательноЗаголовки = Ложь, СообщитьДинамическиеКоординаты = Ложь) Экспорт #Если Сервер И Не Сервер Тогда ТабличныйДокумент = Новый ТабличныйДокумент; #КонецЕсли Результат = Новый Структура("НомерСтрокиЗаголовков, НомерСтрокиДанных"); Результат.НомерСтрокиЗаголовков = СтрокаЗаголовковТД; Результат.НомерСтрокиДанных = ПерваяСтрокаДанныхТД; Если Не ЗначениеЗаполнено(ПерваяСтрокаДанныхТД) Тогда МаксКоличествоЗаполненыхЯчеекДанных = 0; КоличествоЗаполненыхЯчеекЗаголовков = 0; Для НомерСтроки = Макс(1, СтрокаЗаголовковТД) По Мин(10, ТабличныйДокумент.ВысотаТаблицы) Цикл //КоличествоЯчеек = 0; КоличествоЗаполненыхЯчеек = 0; УникальныеЗначения = Новый Соответствие; КоличествоЯчеекСнизу = 0; КоличествоЗаполненыхЯчеекСнизу = 0; КоличествоСовпаденийЯчеекСнизу = 0; МожетБытьСтрокойЗаголовков = Не ЗначениеЗаполнено(СтрокаЗаголовковТД); Для НомерКолонки = 1 По Мин(20, ТабличныйДокумент.ШиринаТаблицы) Цикл ОбластьЦ = ТабличныйДокумент.Область(НомерСтроки, НомерКолонки); //ЛиНезависимаяЯчейка = ОбластьЦ.Верх = НомерСтроки И ОбластьЦ.Лево = НомерКолонки; ОбластьСнизу = ТабличныйДокумент.Область(НомерСтроки + 1, НомерКолонки); ЛиНезависимаяЯчейкаСнизу = ОбластьСнизу.Верх = НомерСтроки + 1 И ОбластьСнизу.Лево = НомерКолонки; Если ЛиНезависимаяЯчейкаСнизу Тогда КоличествоЯчеекСнизу = КоличествоЯчеекСнизу + 1; ТекстЯчейкиСнизу = ОбластьСнизу.Текст; Если ЗначениеЗаполнено(ТекстЯчейкиСнизу) Тогда КоличествоЗаполненыхЯчеекСнизу = КоличествоЗаполненыхЯчеекСнизу + 1; КонецЕсли; КонецЕсли; //Если ЛиНезависимаяЯчейка Тогда // //КоличествоЯчеек = КоличествоЯчеек + 1; ТекстЯчейки = ОбластьЦ.Текст; Если ЗначениеЗаполнено(ТекстЯчейки) Тогда КоличествоЗаполненыхЯчеек = КоличествоЗаполненыхЯчеек + 1; УникальныеЗначения[Лев(ТекстЯчейки, 50)] = 1; // Обрезаем для ускорения КонецЕсли; Если Истина //И ЛиНезависимаяЯчейкаСнизу И ЗначениеЗаполнено(ТекстЯчейки) И ТекстЯчейки = ТекстЯчейкиСнизу Тогда КоличествоСовпаденийЯчеекСнизу = КоличествоСовпаденийЯчеекСнизу + 1; КонецЕсли; //КонецЕсли; //Если Истина // И Не ЛиНезависимаяЯчейка // И ЛиНезависимаяЯчейкаСнизу // И ЗначениеЗаполнено(ТекстЯчейкиСнизу) //Тогда // МожетБытьСтрокойЗаголовков = Ложь; //КонецЕсли; КонецЦикла; Если НомерСтроки = Результат.НомерСтрокиЗаголовков Тогда КоличествоЗаполненыхЯчеекЗаголовков = УникальныеЗначения.Количество(); ИначеЕсли Истина И МожетБытьСтрокойЗаголовков И КоличествоЗаполненыхЯчеекЗаголовков < УникальныеЗначения.Количество() Тогда Результат.НомерСтрокиЗаголовков = НомерСтроки; КоличествоЗаполненыхЯчеекЗаголовков = УникальныеЗначения.Количество(); Если Результат.НомерСтрокиЗаголовков >= Результат.НомерСтрокиДанных Тогда Результат.НомерСтрокиДанных = Результат.НомерСтрокиЗаголовков + 1; МаксКоличествоЗаполненыхЯчеекДанных = 0; КонецЕсли; КонецЕсли; Если КоличествоЗаполненыхЯчеекСнизу > МаксКоличествоЗаполненыхЯчеекДанных Тогда Если КоличествоСовпаденийЯчеекСнизу = 0 Тогда Если КоличествоЗаполненыхЯчеекЗаголовков <= КоличествоЯчеекСнизу Тогда Результат.НомерСтрокиДанных = НомерСтроки + 1; МаксКоличествоЗаполненыхЯчеекДанных = КоличествоЗаполненыхЯчеекСнизу; КонецЕсли; ИначеЕсли Ложь Или МаксКоличествоЗаполненыхЯчеекДанных = 0 Или КоличествоЗаполненыхЯчеек / МаксКоличествоЗаполненыхЯчеекДанных >= 2 Тогда Если КоличествоЗаполненыхЯчеекЗаголовков <= КоличествоЯчеекСнизу Тогда Результат.НомерСтрокиДанных = НомерСтроки; КонецЕсли; КонецЕсли; ИначеЕсли Истина И Не ЗначениеЗаполнено(Результат.НомерСтрокиЗаголовков) И КоличествоЗаполненыхЯчеекСнизу <= КоличествоЗаполненыхЯчеек Тогда Если КоличествоЗаполненыхЯчеекЗаголовков <= КоличествоЯчеекСнизу Тогда Результат.НомерСтрокиДанных = НомерСтроки + 1; КонецЕсли; КонецЕсли; КонецЦикла; Если СообщитьДинамическиеКоординаты Тогда ирОбщий.СообщитьЛкс("Автоподобром найдено заголовки на строке №" + Результат.НомерСтрокиЗаголовков + " и начало данных на строке №" + Результат.НомерСтрокиДанных); КонецЕсли; КонецЕсли; Если ОбязательноЗаголовки И Не ЗначениеЗаполнено(Результат.НомерСтрокиЗаголовков) Тогда Результат.НомерСтрокиЗаголовков = 1; Если Результат.НомерСтрокиДанных <= 1 Тогда Результат.НомерСтрокиДанных = 2; ТабличныйДокумент.ВставитьОбласть(ТабличныйДокумент.Область(1,1), ТабличныйДокумент.Область(1,1), ТипСмещенияТабличногоДокумента.ПоВертикали, Ложь); ТабличныйДокумент.Область(1,1).Текст = ""; КонецЕсли; КонецЕсли; Если СообщитьДинамическиеКоординаты И Не ЗначениеЗаполнено(Результат.НомерСтрокиЗаголовков) Тогда ирОбщий.СообщитьЛкс("Не указан номер строки заголовков и отключен ее автоподбор. Будут использованы сгенерированные заголовки колонок."); КонецЕсли; Возврат Результат; КонецФункции Функция ПолучитьКолонкиТабличногоДокумента(СтруктураПозицийТД = Неопределено, ТолькоВыделенныеСтрокиТД = Ложь) Экспорт СтруктураПозицийТД = Неопределено; КолонкиТабличногоДокумента = Новый Соответствие; мПлатформа = ирКэш.Получить(); #Если Сервер И Не Сервер Тогда мПлатформа = Обработки.ирПлатформа.Создать(); ТабличныйДокумент = Новый ТабличныйДокумент; #КонецЕсли Если СтруктураПозицийТД = Неопределено Тогда СтруктураПозицийТД = СтруктураПозицийТД(); КонецЕсли; НачальнаяСтрока = СтруктураПозицийТД.НомерСтрокиДанных; Если ТолькоВыделенныеСтрокиТД Тогда Если ТабличныйДокумент.ТекущаяОбласть.Верх <= ТабличныйДокумент.ВысотаТаблицы Тогда НачальнаяСтрока = Макс(НачальнаяСтрока, ТабличныйДокумент.ТекущаяОбласть.Верх); КонецЕсли; КонецЕсли; Для Счетчик = 1 По ТабличныйДокумент.ШиринаТаблицы Цикл СинонимКолонки = ""; Если ЗначениеЗаполнено(СтруктураПозицийТД.НомерСтрокиЗаголовков) Тогда СинонимКолонки = ТабличныйДокумент.Область(СтруктураПозицийТД.НомерСтрокиЗаголовков, Счетчик).Текст; КонецЕсли; Если Не ЗначениеЗаполнено(СинонимКолонки) Тогда СинонимКолонки = "Колонка " + Счетчик; КонецЕсли; ИмяКолонки = "" + Счетчик; ПримерДанных = ТабличныйДокумент.Область(НачальнаяСтрока, Счетчик).Текст; КолонкиТабличногоДокумента[ИмяКолонки] = Новый Структура("Имя, Заголовок, ПримерДанных", ИмяКолонки, СинонимКолонки, ПримерДанных); КонецЦикла; Возврат КолонкиТабличногоДокумента; КонецФункции Процедура СообщитьИтогиКонвертации(Знач КоличествоОшибокКонвертации) Если КоличествоОшибокКонвертации Тогда ирОбщий.СообщитьЛкс("Выявлено ячеек, содержащих ошибки/неоднозначное представление: " + КоличествоОшибокКонвертации, СтатусСообщения.Внимание); Иначе ирОбщий.СообщитьЛкс("Не выявлено ячеек, содержащих ошибки"); КонецЕсли; КонецПроцедуры Функция ЗагрузитьВТаблицуБДИзТаблицыЗначений(Параметры) Экспорт ТаблицаИсточник = Параметры.ТаблицаЗначенийОтобранное; Записывать = Параметры.Записывать; ЗаписыватьОбъект = Истина; КоличествоЭлементов = ТаблицаИсточник.Количество(); Если КоличествоЭлементов <= 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; КонецЕсли; ИначеЕсли ЗначениеЗаполнено(СтрокаСопоставления.ИмяКолонкиИсточника) Тогда ОбластьЯчейки = ЯчейкиСтроки[Число(СтрокаСопоставления.ИмяКолонкиИсточника)]; Если ОбластьЯчейки <> Неопределено Тогда Если Не ОбработатьОбласть(ОбластьЯчейки, СтрокаСопоставления, ТекущаяСтрока, ТекстыЯчеек, КэшПоиска) Тогда КоличествоОшибок = КоличествоОшибок + 1; КонецЕсли; КонецЕсли; КонецЕсли; КонецЦикла; Возврат ТекущаяСтрока; КонецФункции // Процедура выполняет обработку области табличного документа: // заполняет расшифровку по представлению ячейки в соответствии со структурой загружаемых реквизитов // сообщает об ошибке и устанавливает коментарий, если ячейка содержит ошибку // // Параметры: // Область - область табличного документа // Колонка - Структура, свойства, в соответствии с которыми необходимо выполнить обработку области // ТекущиеДанные - структура загруженных значений // ТекстыЯчеек - массив текстов ячеек строки // Функция ОбработатьОбласть(Знач Область, СтрокаСопоставления, ТекущиеДанные, ТекстыЯчеек, КэшПоиска) #Если Сервер И Не Сервер Тогда Область = Новый ТабличныйДокумент; Область = Область.Область(); #КонецЕсли Представление = Область.Текст; Если ДобавлятьСырыеДанныеВТЗ Тогда ТекущиеДанные.Вставить(СтрокаСопоставления.ИмяКолонкиПриемника + мСуффиксСырыхДанных, Представление); КонецЕсли; Если СтрокаСопоставления.ОбрезатьКрайниеПробелы Тогда Представление = СокрЛП(Представление); КонецЕсли; ПредставлениеКраткое = ирОбщий.ПредставлениеЗначенияСОграничениемДлиныЛкс(Представление, 50); Примечание = ""; Расшифровка = Область.Расшифровка; Если СтрокаСопоставления.РежимКонвертации = "Вычислять" Тогда Вычисление = ВычислитьЗначениеЯчейки(СтрокаСопоставления.Алгоритм, ТекущиеДанные, Представление, ТекстыЯчеек, СтрокаСопоставления.Значение); Если Не ПустаяСтрока(Вычисление.ОписаниеОшибки) Тогда Результат = Неопределено; Примечание = "Ошибка вычисления: " + Вычисление.ОписаниеОшибки; Иначе Результат = Вычисление.Результат; КонецЕсли; ИначеЕсли Истина И ТипЗнч(Расшифровка) <> Тип("Строка") И ТипЗнч(Расшифровка) <> Тип("ИдентификаторРасшифровкиКомпоновкиДанных") И ТипЗнч(Расшифровка) <> Тип("Неопределено") И СтрокаСопоставления.ОписаниеТипов.СодержитТип(ТипЗнч(Расшифровка)) И Не СтрокаСопоставления.ИгнорироватьРасшифровку Тогда Результат = Расшифровка; ИначеЕсли ПустаяСтрока(Представление) Тогда Результат = Неопределено; Иначе НайденныеЗначения = ПолучитьВозможныеЗначения(СтрокаСопоставления, Представление, Примечание, ТекущиеДанные, КэшПоиска); Если НайденныеЗначения.Количество() = 0 Тогда Примечание = "Не найден" + ?(Примечание = "", "", Символы.ПС+Примечание); Результат = Неопределено; ИначеЕсли НайденныеЗначения.Количество() = 1 Тогда Результат = НайденныеЗначения[0]; Иначе Примечание = "Неоднозначное (" + НайденныеЗначения.Количество() + " вариантов) представление" +?(Примечание = "","", Символы.ПС+Примечание); Нашли = Ложь; НашлиЗначениеПоУмолчанию = Ложь; Для каждого НайденноеЗначение Из НайденныеЗначения Цикл Если НайденноеЗначение = Область.Расшифровка Тогда Нашли = Истина; Прервать; КонецЕсли; Если НайденноеЗначение = СтрокаСопоставления.Значение Тогда НашлиЗначениеПоУмолчанию = Истина; КонецЕсли; КонецЦикла; Если Не Нашли Тогда Если НашлиЗначениеПоУмолчанию Тогда НайденноеЗначение = СтрокаСопоставления.Значение; Иначе НайденноеЗначение = НайденныеЗначения[0]; КонецЕсли; КонецЕсли; Результат = НайденноеЗначение; КонецЕсли; КонецЕсли; Если НЕ ЗначениеЗаполнено(Результат) Тогда Результат = СтрокаСопоставления.Значение; КонецЕсли; ТекущиеДанные.Вставить(СтрокаСопоставления.ИмяКолонкиПриемника, Результат); //Область.Расшифровка = Результат; Если Область.СодержитЗначение Или ЗначениеЗаполнено(Примечание) Тогда // Используем флаг СодержитЗначение для обозначения наличия установленного нами примечания Область.Примечание.Текст = Примечание; // Первое обращение к Область.Примечание выполняется долго, второе в 2 раза быстрее но все равно долго Область.СодержитЗначение = ЗначениеЗаполнено(Примечание); КонецЕсли; Если Не ПустаяСтрока(Примечание) И ВыводитьОшибкиКонвертацииСразу Тогда ирОбщий.СообщитьЛкс("Ячейка["+Область.Имя+"->"+СтрокаСопоставления.СинонимКолонкиПриемника+"](" + ПредставлениеКраткое + "): " + Примечание, СтатусСообщения.Внимание); КонецЕсли; Возврат ПустаяСтрока(Примечание); КонецФункции // Функция возвращает массив возможных значений для текущей колонки по представлению // // Параметры: // Колонка - Структура, свойства, в соответствии с которыми необходимо получить возможные значения // Представление - Строка, по которой необходимо вернуть массив значений // Примечание - массив текстов ячеек строки // ТекущиеДанные - структура загруженных значений // // Возвращаемое значение: // массив возможных значений // Функция ПолучитьВозможныеЗначения(Знач Колонка, Знач Представление, выхПримечание, Знач ТекущиеДанные, КэшПоиска = Неопределено) выхПримечание = ""; НайденныеЗначения = Новый Массив; Если ПустаяСтрока(Представление) Тогда Возврат НайденныеЗначения; КонецЕсли; Если КэшПоиска = Неопределено Тогда КэшПоиска = Новый Соответствие; КонецЕсли; КэшПоискаКолонки = КэшПоиска[Колонка]; Если КэшПоискаКолонки = Неопределено Тогда КэшПоискаКолонки = Новый Соответствие; КэшПоиска[Колонка] = КэшПоискаКолонки; КонецЕсли; ОписаниеТипов = Колонка.ОписаниеТипов; СвязьПоТипу = Неопределено; Если Не ПустаяСтрока(Колонка.СвязьПоТипу) Тогда Если ТипЗНЧ(Колонка.СвязьПоТипу) = Тип("Строка") Тогда ТекущиеДанные.Свойство(Колонка.СвязьПоТипу, СвязьПоТипу); Иначе СвязьПоТипу = Колонка.СвязьПоТипу; КонецЕсли; Если Не СвязьПоТипу = Неопределено Тогда ЭлементСвязиПоТипу = Колонка.ЭлементСвязиПоТипу; Если ЭлементСвязиПоТипу = 0 Тогда ЭлементСвязиПоТипу = 1; КонецЕсли; ВидыСубконто = СвязьПоТипу.ВидыСубконто; Если ЭлементСвязиПоТипу > ВидыСубконто.Количество() Тогда Возврат НайденныеЗначения; КонецЕсли; ОписаниеТипов = СвязьПоТипу.ВидыСубконто[ЭлементСвязиПоТипу-1].ВидСубконто.ТипЗначения; КонецЕсли; КонецЕсли; Для каждого ТипРеквизита Из ОписаниеТипов.Типы() Цикл Если ТипРеквизита = Тип("Null") Тогда НайденныеЗначения.Добавить(Null); ИначеЕсли Ложь Или ТипРеквизита = ПримитивныеТипы.Число Или ТипРеквизита = ПримитивныеТипы.Булево Тогда НайденныеЗначения.Добавить(ирОбщий.СтрокаВЧислоЛкс(Представление, Колонка.ОписаниеТипов, выхПримечание)); ИначеЕсли Ложь Или ТипРеквизита = ПримитивныеТипы.Строка или ТипРеквизита = ПримитивныеТипы.Дата Тогда НайденныеЗначения.Добавить(ирОбщий.СтрокаВДатуЛкс(Представление, Колонка.ОписаниеТипов, выхПримечание, Колонка.АмериканскоеПоложениеМесяца)); ИначеЕсли ТипРеквизита = Тип("УникальныйИдентификатор") Тогда НайденныеЗначения.Добавить(мПривестиКУникальномуИдентификатору(Представление, выхПримечание)); ИначеЕсли ТипРеквизита = Тип("ОписаниеТипов") Тогда НайденныеЗначения.Добавить(мПривестиКОписаниюТипов(Представление, выхПримечание)); Иначе МетаданныеТипа = Метаданные.НайтиПоТипу(ТипРеквизита); Если Перечисления.ТипВсеСсылки().СодержитТип(ТипРеквизита) Тогда //Это Перечисление Для каждого ЗначениеПеречисления Из ирОбщий.ПолучитьМенеджерЛкс(ТипРеквизита) Цикл Если Колонка.ИскатьПо = "Имя" Тогда КлючЗначенияПеречисления = XMLСтрока(ЗначениеПеречисления); Иначе КлючЗначенияПеречисления = Строка(ЗначениеПеречисления); КонецЕсли; Если ирОбщий.СтрокиРавныЛкс(КлючЗначенияПеречисления, Представление) Тогда НайденныеЗначения.Добавить(ЗначениеПеречисления); КонецЕсли; КонецЦикла; ИначеЕсли Документы.ТипВсеСсылки().СодержитТип(ТипРеквизита) Тогда //Это документ //ИскатьПо = Колонка.ИскатьПо; //Если ИскатьПо = "Идентификатор" Тогда СписокДокументов = ирОбщий.ПреобразоватьПредставлениеВСсылкуЛкс(МетаданныеТипа, Представление, КэшПоискаКолонки); Если СписокДокументов <> Неопределено Тогда Если ТипЗнч(СписокДокументов) = Тип("СписокЗначений") Тогда Для Каждого ЭлементСписка Из СписокДокументов Цикл НайденныеЗначения.Добавить(ЭлементСписка.Значение); КонецЦикла; Иначе НайденныеЗначения.Добавить(СписокДокументов); КонецЕсли; КонецЕсли; //Иначе // ДлиннаСинонима = СтрДлина(""+МетаданныеТипа); // Если Лев(Представление, ДлиннаСинонима) = ""+МетаданныеТипа Тогда // НомерИДата = СокрЛП(Сред(Представление, ДлиннаСинонима+1)); // ПозицияОт = Найти(НомерИДата, " от "); // Если Не ПозицияОт = 0 Тогда // НомерДок = Лев(НомерИДата, ПозицияОт-1); // Попытка // ДатаДок = Дата(Сред(НомерИДата, ПозицияОт+4)); // Исключение // ДатаДок = Неопределено; // КонецПопытки; // Если Не ДатаДок = Неопределено Тогда // Менеджер = ирОбщий.ПолучитьМенеджерЛкс(ТипРеквизита); // НайденноеЗначение = Менеджер.НайтиПоНомеру(НомерДок, ДатаДок); // Если Не НайденноеЗначение.Пустая() Тогда // НайденныеЗначения.Добавить(НайденноеЗначение); // КонецЕсли; // КонецЕсли; // КонецЕсли; // КонецЕсли; //КонецЕсли; ИначеЕсли МетаданныеТипа <> Неопределено Тогда ИскатьПо = Колонка.ИскатьПо; Если ИскатьПо = "Идентификатор" Тогда НайденныеЗначения.Добавить(ирОбщий.ПреобразоватьПредставлениеВСсылкуЛкс(МетаданныеТипа, Представление)); Иначе ПоляТаблицыБД = ирКэш.ПоляТаблицыБДЛкс(МетаданныеТипа.ПолноеИмя()); НайденныеЗначения = КэшПоискаКолонки[Представление]; Если НайденныеЗначения = Неопределено Тогда НайденныеЗначения = Новый Массив; ЭтоСправочник = Справочники.ТипВсеСсылки().СодержитТип(ТипРеквизита); Если ПустаяСтрока(ИскатьПо) Или ПоляТаблицыБД.Найти(ИскатьПо) = Неопределено Тогда СтрокаОсновногоПредставления = Строка(МетаданныеТипа.ОсновноеПредставление); Если СтрокаОсновногоПредставления = "ВВидеКода" Тогда ИскатьПо = "Код"; ИначеЕсли СтрокаОсновногоПредставления = "ВВидеНаименования" Тогда ИскатьПо = "Наименование"; ИначеЕсли СтрокаОсновногоПредставления = "ВВидеНомера" Тогда ИскатьПо = "Номер"; КонецЕсли; КонецЕсли; Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | _Таблица.Ссылка |ИЗ | " + МетаданныеТипа.ПолноеИмя() + " КАК _Таблица |ГДЕ"; Запрос.Текст = Запрос.Текст + " | _Таблица." + ИскатьПо + " = &Представление"; Запрос.УстановитьПараметр("Представление",Представление); Если Истина И ЭтоСправочник И Не ПустаяСтрока(Колонка.СвязьПоВладельцу) И Колонка.СвязьПоВладельцу <> "<Создаваемый объект>" И МетаданныеТипа.Владельцы.Количество() > 0 Тогда СвязьПоВладельцу = Неопределено; Если ТипЗНЧ(Колонка.СвязьПоВладельцу) = Тип("Строка") Тогда ТекущиеДанные.Свойство(Колонка.СвязьПоВладельцу, СвязьПоВладельцу); Иначе СвязьПоВладельцу = Колонка.СвязьПоВладельцу; КонецЕсли; Если СвязьПоВладельцу <> Неопределено Тогда Запрос.Текст = Запрос.Текст + " | И _Таблица.Владелец = &СвязьПоВладельцу"; Запрос.УстановитьПараметр("СвязьПоВладельцу", СвязьПоВладельцу); КонецЕсли; КонецЕсли; Выборка = Запрос.Выполнить().Выбрать(); Пока Выборка.Следующий() Цикл НайденныеЗначения.Добавить(Выборка.Ссылка); КонецЦикла; КэшПоискаКолонки[Представление] = НайденныеЗначения; КонецЕсли; КонецЕсли; Иначе выхПримечание = "Для типа значения """ + ТипРеквизита + """ не описан способ поиска"; КонецЕсли; КонецЕсли; КонецЦикла; Возврат НайденныеЗначения; КонецФункции Функция мПолучитьНастройку(ДляФайла = Ложь) Экспорт #Если Сервер И Не Сервер Тогда ТабличныйДокумент = Новый ТабличныйДокумент; #КонецЕсли ДокументРезультат = Новый Структура; ДокументРезультат.Вставить("ВыводитьОшибкаЗагрузкиСразу", ВыводитьОшибкаЗагрузкиСразу); ДокументРезультат.Вставить("ВыводитьОшибкиКонвертацииСразу", ВыводитьОшибкиКонвертацииСразу); ДокументРезультат.Вставить("ДополнятьЗапросом", ДополнятьЗапросом); ДокументРезультат.Вставить("ДобавлятьСтрокиБД", ДобавлятьСтрокиБД); ДокументРезультат.Вставить("ОбновлятьСтрокиБД", ОбновлятьСтрокиБД); ДокументРезультат.Вставить("ВыполнятьНаСервере", ВыполнятьНаСервере); ДокументРезультат.Вставить("КоличествоПотоков", КоличествоПотоков); ДокументРезультат.Вставить("КоличествоОбъектовВПорции", КоличествоОбъектовВПорции); ДокументРезультат.Вставить("ПолноеИмяТаблицы", мТекущееПолноеИмяТаблицы); // Для загрузки настройки из файла ДокументРезультат.Вставить("СобытияОбработкиОбъектов", СобытияОбработкиОбъектов.Скопировать(, "ИмяСобытия, Алгоритм")); ДокументРезультат.Вставить("ПерваяСтрокаДанныхТД", ПерваяСтрокаДанныхТД); ДокументРезультат.Вставить("СтрокаЗаголовковТД", СтрокаЗаголовковТД); ДокументРезультат.Вставить("СопоставлениеКолонокТЗ", СопоставлениеКолонокТЗ.Скопировать()); ДокументРезультат.Вставить("СопоставлениеКолонокБД", СопоставлениеКолонокБД.Скопировать()); ДокументРезультат.Вставить("НастройкаКомпоновки", ТаблицаЗначенийКомпоновщик.ПолучитьНастройки()); ДокументРезультат.Вставить("ТаблицаЗначенийИспользоватьОтбор", ТаблицаЗначенийИспользоватьОтбор); ДокументРезультат.Вставить("ДобавлятьСырыеДанныеВТЗ", ДобавлятьСырыеДанныеВТЗ); Если мКонсольЗапросов <> Неопределено Тогда ДополнениеЗапросом = мКонсольЗапросов.ДеревоЗапросов.Скопировать(); КонецЕсли; СтруктураПозицийТД = СтруктураПозицийТД(); ДокументРезультат.Вставить("ДополнениеЗапросом", ДополнениеЗапросом); Если ДляФайла Или СохранятьДанныеТД Тогда ДокументРезультат.Вставить("ТабличныйДокумент", ТабличныйДокумент.ПолучитьОбласть()); Если Не ДляФайла И ТабличныйДокумент.ВысотаТаблицы > 1000 Тогда ирОбщий.СообщитьЛкс("В хранилище настроек БД помещено большое количество строк табличного документа. Рекомендуется хранить такие настройки в файлах"); КонецЕсли; ИначеЕсли ЗначениеЗаполнено(СтруктураПозицийТД.НомерСтрокиЗаголовков) Тогда ДокументРезультат.Вставить("ТабличныйДокумент", ТабличныйДокумент.ПолучитьОбласть(СтруктураПозицийТД.НомерСтрокиЗаголовков, 1, СтруктураПозицийТД.НомерСтрокиЗаголовков, ТабличныйДокумент.ШиринаТаблицы)); Иначе ДокументРезультат.Вставить("ТабличныйДокумент", Новый ТабличныйДокумент); КонецЕсли; Если ДляФайла Или СохранятьДанныеТЗ Тогда ДокументРезультат.Вставить("ТаблицаЗначений", ТаблицаЗначений.Скопировать()); Если Не ДляФайла И ТаблицаЗначений.Количество() > 5000 Тогда ирОбщий.СообщитьЛкс("В хранилище настроек БД помещено большое количество строк таблицы значений. Рекомендуется хранить такие настройки в файлах"); КонецЕсли; Иначе ДокументРезультат.Вставить("ТаблицаЗначений", ТаблицаЗначений.СкопироватьКолонки()); КонецЕсли; Возврат ДокументРезультат; КонецФункции // () Процедура мЗагрузитьНастройку(Настройка, ЗаменитьДанныеТДиТЗ = Истина, ЗаменитьМетаданныеТДиТЗ = Истина) Экспорт #Если Сервер И Не Сервер Тогда Настройка = Новый Структура; #КонецЕсли мДополнениеЗапросом = Неопределено; Если Настройка <> Неопределено Тогда Если ЗаменитьДанныеТДиТЗ Тогда Если Настройка.Свойство("ШапкаТабличногоДокумента") Тогда // Старый формат НовыйТабличныйДокумент = Настройка.ШапкаТабличногоДокумента; Иначе НовыйТабличныйДокумент = Настройка.ТабличныйДокумент; КонецЕсли; // Это нужно делать до загрузки свойства СохранятьДанныеТД через ЗаполнитьЗначенияСвойств! ТабличныйДокумент.Очистить(); ТабличныйДокумент.Вывести(НовыйТабличныйДокумент); КонецЕсли; Если Не Настройка.Свойство("ДополнятьЗапросом") Тогда Настройка.Вставить("ДополнятьЗапросом", Ложь); КонецЕсли; Если Не Настройка.Свойство("ДополнениеЗапросом") Тогда Настройка.Вставить("ДополнениеЗапросом"); КонецЕсли; Если Не Настройка.Свойство("НастройкаКомпоновки") Тогда Настройка.Вставить("НастройкаКомпоновки", Новый НастройкиКомпоновкиДанных); КонецЕсли; ЗаполнитьЗначенияСвойств(ЭтотОбъект, Настройка,, "ТабличныйДокумент, ТаблицаЗначений, СобытияОбработкиОбъектов, СопоставлениеКолонокТЗ, СопоставлениеКолонокБД, ПолноеИмяТаблицы, ДополнятьЗапросом"); Если ЗаменитьДанныеТДиТЗ Тогда ТаблицаЗначений.Очистить(); ЭтотОбъект.ТаблицаЗначений = Настройка.ТаблицаЗначений.Скопировать(); КонецЕсли; Если ЗаменитьМетаданныеТДиТЗ Тогда СопоставлениеКолонокТЗ.Очистить(); ирОбщий.ЗагрузитьВТаблицуЗначенийЛкс(Настройка.СопоставлениеКолонокТЗ, СопоставлениеКолонокТЗ); СобытияОбработкиОбъектов.ЗаполнитьЗначения(, "Алгоритм, АлгоритмОбъект"); Если Настройка.Свойство("СобытияОбработкиОбъектов") Тогда Для Каждого СохраненнаяСтрокаСобытияОбработкиОбъектов Из Настройка.СобытияОбработкиОбъектов Цикл СтрокаСобытияОбработкиОбъектов = СобытияОбработкиОбъектов.Найти(СохраненнаяСтрокаСобытияОбработкиОбъектов.ИмяСобытия, "ИмяСобытия"); СтрокаСобытияОбработкиОбъектов.Алгоритм = СохраненнаяСтрокаСобытияОбработкиОбъектов.Алгоритм; КонецЦикла; КонецЕсли; мДополнениеЗапросом = Настройка.ДополнениеЗапросом; ЭтотОбъект.ДополнятьЗапросом = мДополнениеЗапросом <> Неопределено И Настройка.ДополнятьЗапросом; ТаблицаЗначенийКомпоновщик.ЗагрузитьНастройки(Настройка.НастройкаКомпоновки); КонецЕсли; Если Настройка.Свойство("ПолноеИмяТаблицы") И ирОбщий.СтрокиРавныЛкс(Настройка.ПолноеИмяТаблицы, ПолноеИмяТаблицы) Тогда ирОбщий.ЗагрузитьВТаблицуЗначенийЛкс(Настройка.СопоставлениеКолонокБД, СопоставлениеКолонокБД,,, Истина); ЗаполнитьСопоставлениеКолонокБД(); КонецЕсли; Иначе ОбновитьСопоставлениеКолонокТЗ(); КонецЕсли; СопоставлениеКолонокТЗЗаполнить(Ложь); СопоставлениеКолонокБДЗаполнитьПоИменамСинонимам(); КонецПроцедуры // Функция возвращает список, элементами которого выступают возможные имена представления загружаемого реквизита // // Параметры: // ЗагружаемыйРеквизит - Строка таблицы значений загружаемого реквизита // // Возвращаемое значение: // список значений; значение списка - строка имя представления // Функция ПолучитьСписокИменПредставлений(ЗагружаемыйРеквизит) Экспорт СписокВыбора = Новый СписокЗначений; Если ЗагружаемыйРеквизит.ОписаниеТипов.Типы().Количество() = 1 Тогда Тип = ЗагружаемыйРеквизит.ОписаниеТипов.Типы()[0]; МетаданныеТипа = Метаданные.НайтиПоТипу(Тип); Если МетаданныеТипа <> Неопределено Тогда ПолноеИмяМД = МетаданныеТипа.ПолноеИмя(); КорневойТип = ирОбщий.ПервыйФрагментЛкс(ПолноеИмяМД); КонецЕсли; ЭтоСправочник = Справочники.ТипВсеСсылки().СодержитТип(Тип); ЭтоСчет = ПланыСчетов.ТипВсеСсылки().СодержитТип(Тип); ЭтоВидХарактеристик = ПланыВидовХарактеристик.ТипВсеСсылки().СодержитТип(Тип); Если ЭтоСправочник ИЛИ ЭтоСчет Или ЭтоВидХарактеристик Тогда ЕстьКод = МетаданныеТипа.ДлинаКода > 0; ЕстьИмя = МетаданныеТипа.ДлинаНаименования > 0; ВидОсновногоПредставление = ?(ЭтоСправочник, Метаданные.СвойстваОбъектов.ОсновноеПредставлениеСправочника, ?(ЭтоСчет,Метаданные.СвойстваОбъектов.ОсновноеПредставлениеСчета,Метаданные.СвойстваОбъектов.ОсновноеПредставлениеВидаХарактеристики)); Если МетаданныеТипа.ОсновноеПредставление = ВидОсновногоПредставление.ВВидеКода Тогда Если ЕстьКод Тогда СписокВыбора.Добавить("Код", "Код"); КонецЕсли; Если ЕстьИмя Тогда СписокВыбора.Добавить("Наименование", "Наименование"); КонецЕсли; Иначе Если ЕстьИмя Тогда СписокВыбора.Добавить("Наименование", "Наименование"); КонецЕсли; Если ЕстьКод Тогда СписокВыбора.Добавить("Код", "Код"); КонецЕсли; КонецЕсли; Для каждого Реквизит Из МетаданныеТипа.Реквизиты Цикл Если Не Реквизит.Индексирование = Метаданные.СвойстваОбъектов.Индексирование.НеИндексировать И Реквизит.Тип.Типы().Количество() = 1 и Реквизит.Тип.Типы()[0] = Тип ("Строка") Тогда СписокВыбора.Добавить(Реквизит.Имя, Реквизит.Представление()); КонецЕсли; КонецЦикла; КонецЕсли; Если ирОбщий.ЛиКорневойТипПеречисленияЛкс(КорневойТип) Тогда СписокВыбора.Добавить("Синоним"); СписокВыбора.Добавить("Имя"); ИначеЕсли Документы.ТипВсеСсылки().СодержитТип(Тип) Тогда СписокВыбора.Добавить("Авто", "<Авто>"); ИначеЕсли МетаданныеТипа <> Неопределено Тогда СписокВыбора.Добавить("Идентификатор", "<Идентификатор>"); КонецЕсли; КонецЕсли; Возврат СписокВыбора; КонецФункции // () Функция ПолучитьСписокСвязейПоВладельцу(ЗагружаемыйРеквизит) Экспорт ЕстьТипСамогоОбъекта = Ложь; Если мЭтоСсылочныйОбъект Тогда ОписаниеТиповСправочника = Тип(СтрЗаменить(ПолноеИмяТаблицы, ".", "Ссылка.")); КонецЕсли; СписокВыбора = Новый СписокЗначений; ТипыВладельцев = Новый Соответствие; Для каждого ТипКолонки Из ЗагружаемыйРеквизит.ОписаниеТипов.Типы() Цикл Если Справочники.ТипВсеСсылки().СодержитТип(ТипКолонки) Тогда Для каждого Владелец Из Метаданные.НайтиПоТипу(ТипКолонки).Владельцы Цикл ТипВладельца = Тип(СтрЗаменить(Владелец.ПолноеИмя(), ".", "Ссылка.")); Если ТипыВладельцев[ТипВладельца] = Неопределено Тогда Если ТипВладельца = ОписаниеТиповСправочника Тогда ЕстьТипСамогоОбъекта = Истина; КонецЕсли; ТипыВладельцев.Вставить(ТипВладельца, Владелец.ПолноеИмя()); Для каждого КолонкаСвязиПоВладельцу Из СопоставлениеКолонокТЗ Цикл Если КолонкаСвязиПоВладельцу.ОписаниеТипов.Типы()[0] = ТипВладельца Тогда // Возможно надо будет по всем типам проходить СписокВыбора.Добавить(КолонкаСвязиПоВладельцу.ИмяКолонкиПриемника,КолонкаСвязиПоВладельцу.ИмяКолонкиПриемника); КонецЕсли; КонецЦикла; КонецЕсли; КонецЦикла; КонецЕсли; КонецЦикла; Если Не ТипыВладельцев.Количество() = 0 Тогда СписокВыбора.Добавить(Неопределено, "<пустое значение>"); КонецЕсли; Для каждого КлючИЗначение Из ТипыВладельцев Цикл СписокВыбора.Добавить(СтрЗаменить(КлючИЗначение.Значение, ".", "Ссылка."), "<"+КлючИЗначение.Значение+">"); КонецЦикла; Если ЕстьТипСамогоОбъекта Тогда СписокВыбора.Вставить(0, "<Создаваемый объект>", "<Создаваемый объект>"); КонецЕсли; Возврат СписокВыбора; КонецФункции // () // Функция возвращает список, элементами которого выступают возможные связи по типу для загружаемого реквизита // // Параметры: // ЗагружаемыйРеквизит - Строка таблицы значений загружаемого реквизита // // Возвращаемое значение: // список значений; значение списка - строка имя колонки связи или ссылка на элемент связи // Функция ПолучитьСписокСвязейПоТипу(ЗагружаемыйРеквизит) Экспорт СписокВыбора = Новый СписокЗначений; ВозможныеПланыСчетов = Новый Структура; Для каждого ПланСчетов Из Метаданные.ПланыСчетов Цикл Если ПланСчетов.ВидыСубконто <> Неопределено И ПланСчетов.ВидыСубконто.Тип = ЗагружаемыйРеквизит.ОписаниеТипов Тогда ВозможныеПланыСчетов.Вставить(ПланСчетов.Имя,ПланыСчетов[ПланСчетов.Имя]); КонецЕсли; КонецЦикла; Для каждого ПланСчетов Из ВозможныеПланыСчетов Цикл ТипЗНЧПланСчетов = ТипЗНЧ(ПланСчетов.Значение.ПустаяСсылка()); Для каждого КолонкаСвязиПоТипу Из СопоставлениеКолонокТЗ Цикл Если КолонкаСвязиПоТипу.ОписаниеТипов.Типы()[0] = ТипЗНЧПланСчетов Тогда СписокВыбора.Добавить(КолонкаСвязиПоТипу.ИмяКолонкиПриемника,КолонкаСвязиПоТипу.ИмяКолонкиПриемника); КонецЕсли; КонецЦикла; КонецЦикла; Если Не ВозможныеПланыСчетов.Количество() = 0 Тогда СписокВыбора.Добавить(Неопределено, "< пустое значение >"); КонецЕсли; Для каждого ПланСчетов Из ВозможныеПланыСчетов Цикл СписокВыбора.Добавить("ПланСчетовСсылка."+ПланСчетов.Ключ,"<"+ПланСчетов.Ключ+">"); КонецЦикла; Возврат СписокВыбора; КонецФункции // () Процедура ЗаполнитьСопоставлениеКолонокБД() Экспорт КопияСопоставления = СопоставлениеКолонокБД.Скопировать(); СопоставлениеКолонокБД.Очистить(); Если Не ЗначениеЗаполнено(ПолноеИмяТаблицы) Тогда Возврат; КонецЕсли; МетаданныеИсточника = МетаданныеТаблицыБД(); ПоляТаблицы = ирОбщий.ПоляТаблицыБДЛкс(ПолноеИмяТаблицы); СтруктураКлючаОбъекта = ирОбщий.СтруктураКлючаТаблицыБДЛкс(ПолноеИмяТаблицы, Ложь); МассивВозможныхПолейПоиска = Новый Массив; МассивВозможныхПолейПоиска.Добавить("Код"); МассивВозможныхПолейПоиска.Добавить("Наименование"); МассивВозможныхПолейПоиска.Добавить("Период"); МассивВозможныхПолейПоиска.Добавить("Регистратор"); МассивВозможныхПолейПоиска.Добавить("НомерСтроки"); МассивВозможныхПолейПоиска.Добавить("Ссылка"); МассивВозможныхПолейПоиска.Добавить("Номер"); МассивВозможныхПолейПоиска.Добавить("Владелец"); МассивВозможныхПолейПоиска.Добавить("Дата"); МассивВозможныхПолейПоиска.Добавить("Родитель"); МассивВозможныхПолейПоиска.Добавить("ЭтоГруппа"); ТипТаблицыБД = ирОбщий.ТипТаблицыБДЛкс(ПолноеИмяТаблицы); Если ирОбщий.ЛиКорневойТипРегистраБДЛкс(ТипТаблицыБД) Тогда Для каждого МетаИзмерение Из МетаданныеИсточника.Измерения Цикл МассивВозможныхПолейПоиска.Добавить(МетаИзмерение.Имя); КонецЦикла; КонецЕсли; Для Каждого ПолеТаблицы Из ПоляТаблицы Цикл Если Ложь Или ПолеТаблицы.ТипЗначения.СодержитТип(Тип("ТаблицаЗначений")) //Или ПолеТаблицы.ТипЗначения.СодержитТип(Тип("ХранилищеЗначения")) //Или (Истина // И ПолеТаблицы.Метаданные = Неопределено // И (Ложь // Или ПолеТаблицы.Имя = "ВерсияДанных" // Или ПолеТаблицы.Имя = "Предопределенный")) Тогда Продолжить; КонецЕсли; ЗагружаемыйРеквизит = СопоставлениеКолонокБД.Добавить(); ЗагружаемыйРеквизит.ИмяКолонкиПриемника = ПолеТаблицы.Имя; ЗагружаемыйРеквизит.СинонимКолонкиПриемника = ПолеТаблицы.Заголовок; ЗагружаемыйРеквизит.ОписаниеТиповПриемника = ПолеТаблицы.ТипЗначения; ЗагружаемыйРеквизит.ДоступноИзменение = Истина И Не (Истина И ирОбщий.ЛиТипВложеннойТаблицыБДЛкс(ТипТаблицыБД) И (Ложь Или ПолеТаблицы.Имя = "Ссылка" Или ПолеТаблицы.Имя = "НомерСтроки")) И (Ложь Или Не мЭтоСсылочныйОбъект Или Не ирОбщий.НедоступноИзменениеПоляСсылочногоОбъектаЛкс(ПолеТаблицы.Имя)); Если ирОбщий.ЛиМетаданныеОбъектаСГруппамиЛкс(МетаданныеИсточника) Тогда Если Истина И ТипЗнч(ПолеТаблицы.Метаданные) = Тип("ОбъектМетаданных") И (Ложь Или ирКэш.НомерВерсииПлатформыЛкс() < 802014 Или Метаданные.ОбщиеРеквизиты.Найти(ПолеТаблицы.Метаданные.Имя) = Неопределено) Тогда ЗагружаемыйРеквизит.Принадлежность = ПолеТаблицы.Метаданные.Использование; Иначе ЗагружаемыйРеквизит.Принадлежность = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляГруппыИЭлемента; КонецЕсли; КонецЕсли; Если СтруктураКлючаОбъекта.Свойство(ПолеТаблицы.Имя) Тогда ЗагружаемыйРеквизит.Ключевое = Истина; ЗагружаемыйРеквизит.ПолеПоиска = Не мЭтоСсылочныйОбъект; КонецЕсли; Если ПолеТаблицы.Метаданные <> Неопределено Тогда ЗагружаемыйРеквизит.Подсказка = ПолеТаблицы.Метаданные.Подсказка; КонецЕсли; ЗагружаемыйРеквизит.Значение = ЗагружаемыйРеквизит.ОписаниеТиповПриемника.ПривестиЗначение(Неопределено); ВосстановитьИзменяемыеСвойстваСтрокиСопоставленияБД(ЗагружаемыйРеквизит, КопияСопоставления); Если СтруктураКлючаОбъекта.Свойство(ПолеТаблицы.Имя) Тогда ЗагружаемыйРеквизит.Пометка = Не мЭтоСсылочныйОбъект; //ЗагружаемыйРеквизит.ПолеПоиска = Не мЭтоСсылочныйОбъект; КонецЕсли; КонецЦикла; Если ирОбщий.ЛиКорневойТипСсылочногоОбъектаБДЛкс(ТипТаблицыБД) Тогда ТипСсылки = Тип(ирОбщий.ИмяТипаИзПолногоИмениМДЛкс(МетаданныеИсточника)); СписокСвойств = ирОбщий.ДопРеквизитыБСПОбъектаЛкс(Новый(ТипСсылки)); Для Каждого Свойство Из СписокСвойств Цикл #Если Сервер И Не Сервер Тогда Свойство = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.ПустаяСсылка(); #КонецЕсли ЗагружаемыйРеквизит = СопоставлениеКолонокБД.Добавить(); ЗагружаемыйРеквизит.ОписаниеТиповПриемника = Свойство.ТипЗначения; ЗагружаемыйРеквизит.ИмяКолонкиПриемника = Свойство.Имя; ЗагружаемыйРеквизит.СинонимКолонкиПриемника = Свойство.Наименование; ЗагружаемыйРеквизит.Принадлежность = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляГруппыИЭлемента; ЗагружаемыйРеквизит.ДопРеквизит = Свойство; ЗагружаемыйРеквизит.Подсказка = Свойство.Подсказка; ЗагружаемыйРеквизит.ДоступноИзменение = Истина; ВосстановитьИзменяемыеСвойстваСтрокиСопоставленияБД(ЗагружаемыйРеквизит, КопияСопоставления); КонецЦикла; КонецЕсли; СопоставлениеКолонокБД.Сортировать("СинонимКолонкиПриемника"); СопоставлениеКолонокБДЗаполнитьПоИменамСинонимам(Ложь); ВыявитьНеуникальныеКлючи(); КонецПроцедуры Процедура ВосстановитьИзменяемыеСвойстваСтрокиСопоставленияБД(Знач ЗагружаемыйРеквизит, Знач КопияСопоставления) СтараяСтрока = КопияСопоставления.Найти(ЗагружаемыйРеквизит.ИмяКолонкиПриемника, "ИмяКолонкиПриемника"); Если СтараяСтрока <> Неопределено Тогда ЗаполнитьЗначенияСвойств(ЗагружаемыйРеквизит, СтараяСтрока, "ИзИсточника, ПолеПоиска, Пометка, Значение"); Если ЗагружаемыйРеквизит.ИзИсточника Тогда СопоставитьКолонкуБД(ЗагружаемыйРеквизит, ТаблицаЗначений.Колонки.Найти(СтараяСтрока.ИмяКолонкиИсточника)); КонецЕсли; КонецЕсли; КонецПроцедуры Функция ВыявитьНеуникальныеКлючи(выхСтрокаКлючаИсточника = "") Экспорт выхСтрокаКлючаИсточника = Новый Массив; Для Каждого СтрокаСопоставления Из СопоставлениеКолонокБД.НайтиСтроки(Новый Структура("ПолеПоиска", Истина)) Цикл Если Истина И ЗначениеЗаполнено(СтрокаСопоставления.ИмяКолонкиИсточника) И выхСтрокаКлючаИсточника.Найти(СтрокаСопоставления.ИмяКолонкиИсточника) = Неопределено Тогда выхСтрокаКлючаИсточника.Добавить(СтрокаСопоставления.ИмяКолонкиИсточника); КонецЕсли; КонецЦикла; выхСтрокаКлючаИсточника = ирОбщий.СтрСоединитьЛкс(выхСтрокаКлючаИсточника); НеуникальныеКлючи = ирОбщий.НеуникальныеКлючиТаблицыЛкс(ТаблицаЗначений, выхСтрокаКлючаИсточника); ЭтотОбъект.КоличествоНеуникально = НеуникальныеКлючи.Количество(); Возврат НеуникальныеКлючи; КонецФункции Процедура СопоставлениеКолонокБДЗаполнитьПоИменамСинонимам(РазрешитьМенятьИзИсточника = Истина) Экспорт Для Каждого Колонка Из ТаблицаЗначений.Колонки Цикл Если Колонка.Имя = мИмяКолонкиНомерСтроки Тогда Продолжить; КонецЕсли; СтрокаИмен = ""; СтруктураОтбора = Новый Структура("СинонимКолонкиИсточника", ""); СтрокиСопоставления = СопоставлениеКолонокБД.НайтиСтроки(СтруктураОтбора); // Сначала ищем пару по пересечению типов и именам Для Каждого СтрокаСопоставления Из СтрокиСопоставления Цикл Если Не ирОбщий.ЛиОписаниеТипов1ВходитВОписаниеТипов2Лкс(Колонка.ТипЗначения, СтрокаСопоставления.ОписаниеТиповПриемника) Тогда Продолжить; КонецЕсли; Если Ложь Или ирОбщий.СтрокиРавныЛкс(СтрокаСопоставления.ИмяКолонкиПриемника, Колонка.Имя) Или ирОбщий.СтрокиРавныЛкс(СтрокаСопоставления.СинонимКолонкиПриемника, Колонка.Заголовок) Тогда СопоставитьКолонкуБД(СтрокаСопоставления, Колонка, РазрешитьМенятьИзИсточника); СтрокаИмен = СтрокаИмен + ", " + СтрокаСопоставления.ИмяКолонкиПриемника; КонецЕсли; КонецЦикла; СтрокиСопоставления = СопоставлениеКолонокБД.НайтиСтроки(СтруктураОтбора); // Затем ищем пару по совпадаению ссылочного моно типа Для Каждого СтрокаСопоставления Из СтрокиСопоставления Цикл Если Не ирОбщий.ЛиОписаниеТипов1ВходитВОписаниеТипов2Лкс(Колонка.ТипЗначения, СтрокаСопоставления.ОписаниеТиповПриемника) Тогда Продолжить; КонецЕсли; Если Истина И Колонка.ТипЗначения.Типы().Количество() = 1 И ирОбщий.ЛиТипСсылкиБДЛкс(Колонка.ТипЗначения.Типы()[0]) И СтрокаСопоставления.ОписаниеТиповПриемника.Типы().Количество() = 1 Тогда СопоставитьКолонкуБД(СтрокаСопоставления, Колонка, РазрешитьМенятьИзИсточника); СтрокаИмен = СтрокаИмен + ", " + СтрокаСопоставления.ИмяКолонкиПриемника; КонецЕсли; КонецЦикла; Если СтрокиСопоставления.Количество() > 0 Тогда СтрокаКолонки = КолонкиТЗ.Найти(Колонка.Имя, "ИмяКолонки"); Если СтрокаКолонки <> Неопределено Тогда СтрокаКолонки.КолонкиПриемника = СтрокаКолонки.КолонкиПриемника + СтрокаИмен; КонецЕсли; КонецЕсли; КонецЦикла; КонецПроцедуры Процедура ОбновитьКолонкиТаблицыБД(ОчиститьСуществующие = Истина, ДобавитьКолонкуРезультатаЗаписи = Истина) Экспорт Если ОчиститьСуществующие Тогда ТаблицаБД.Очистить(); ТаблицаБД.Колонки.Очистить(); КонецЕсли; ПроверитьДобавитьКолонкуИдентификатораСтроки(ТаблицаБД); Если ТаблицаБД.Колонки.Найти(мИмяКолонкиРезультатПоиска) = Неопределено Тогда ТаблицаБД.Колонки.Добавить(мИмяКолонкиРезультатПоиска, Новый ОписаниеТипов("Строка"), "<Результат поиска>"); КонецЕсли; Если ДобавитьКолонкуРезультатаЗаписи Тогда Если ТаблицаБД.Колонки.Найти(мИмяКолонкиРезультатЗаписи) = Неопределено Тогда ТаблицаБД.Колонки.Добавить(мИмяКолонкиРезультатЗаписи, Новый ОписаниеТипов("Строка"), "<Результат записи>"); КонецЕсли; Если ТаблицаБД.Колонки.Найти(мИмяКолонкиСообщенияОбработки) = Неопределено Тогда ТаблицаБД.Колонки.Добавить(мИмяКолонкиСообщенияОбработки, Новый ОписаниеТипов("Строка"), "<Сообщения>"); КонецЕсли; КонецЕсли; СтруктураКлючаОбъекта = ирОбщий.СтруктураКлючаТаблицыБДЛкс(ПолноеИмяТаблицы); Для каждого КлючИЗначение Из СтруктураКлючаОбъекта Цикл СтрокаСопоставленияБД = СопоставлениеКолонокБД.Найти(КлючИЗначение.Ключ, "ИмяКолонкиПриемника"); ТаблицаБД.Колонки.Добавить(СтрокаСопоставленияБД.ИмяКолонкиПриемника, СтрокаСопоставленияБД.ОписаниеТиповПриемника, СтрокаСопоставленияБД.СинонимКолонкиПриемника + " (ключ)"); КонецЦикла; КопияСопоставленияБД = СопоставлениеКолонокБД.Скопировать(); КопияСопоставленияБД.Сортировать("ПолеПоиска Убыв, Пометка Убыв"); Для каждого СтрокаСопоставленияБД Из КопияСопоставленияБД Цикл Если Ложь Или СтруктураКлючаОбъекта.Свойство(СтрокаСопоставленияБД.ИмяКолонкиПриемника) // Колонка уже добавлена выше Или (Истина И Не СтрокаСопоставленияБД.ПолеПоиска И Не СтрокаСопоставленияБД.Пометка) Тогда Продолжить; КонецЕсли; ЗаголовокКолонки = СтрокаСопоставленияБД.СинонимКолонкиПриемника; Если СтрокаСопоставленияБД.ПолеПоиска Тогда ЗаголовокКолонки = ЗаголовокКолонки + " (поиск)"; ИначеЕсли Не СтрокаСопоставленияБД.Пометка Тогда ЗаголовокКолонки = ЗаголовокКолонки + " (новая)"; КонецЕсли; ТаблицаБД.Колонки.Добавить(СтрокаСопоставленияБД.ИмяКолонкиПриемника, СтрокаСопоставленияБД.ОписаниеТиповПриемника, ЗаголовокКолонки); КонецЦикла; КонецПроцедуры Процедура ПроверитьДобавитьКолонкуИдентификатораСтроки(Таблица) Экспорт Если Таблица.Колонки.Найти(мИмяКолонкиНомерСтроки) = Неопределено Тогда Таблица.Колонки.Вставить(0, мИмяКолонкиНомерСтроки, Новый ОписаниеТипов("Число"), "<№>"); Счетчик = 1; Для Каждого СтрокаТаблицы Из Таблица Цикл СтрокаТаблицы[мИмяКолонкиНомерСтроки] = Счетчик; Счетчик = Счетчик + 1; КонецЦикла; КонецЕсли; КонецПроцедуры Процедура СопоставлениеКолонокТЗЗаполнить(УстановитьПометкуДляСопоставленных = Истина) Экспорт ОбновитьСопоставлениеКолонокТЗ(УстановитьПометкуДляСопоставленных); КолонкиТабличногоДокумента = ПолучитьКолонкиТабличногоДокумента(); Для Каждого КлючИЗначение Из КолонкиТабличногоДокумента Цикл Колонка = КлючИЗначение.Значение; СтруктураОтбора = Новый Структура("СинонимКолонкиИсточника", ""); СтрокиСопоставления = СопоставлениеКолонокТЗ.НайтиСтроки(СтруктураОтбора); КолонкаСопоставлена = Ложь; Для Каждого СтрокаСопоставления Из СтрокиСопоставления Цикл Если ирОбщий.СтрокиРавныЛкс(СтрокаСопоставления.СинонимКолонкиПриемника, Колонка.Заголовок) Тогда СопоставитьКолонкуТЗ(СтрокаСопоставления, Колонка); КолонкаСопоставлена = Истина; Прервать; КонецЕсли; КонецЦикла; Если КолонкаСопоставлена Тогда СтрокаКолонки = НесопоставленныеКолонкиТД.Найти(Колонка.Имя, "ИмяКолонки"); Если СтрокаКолонки <> Неопределено Тогда НесопоставленныеКолонкиТД.Удалить(СтрокаКолонки); КонецЕсли; КонецЕсли; КонецЦикла; КонецПроцедуры Процедура СопоставитьКолонкуБД(Знач СтрокаСопоставления, Знач Колонка = Неопределено, РазрешитьМенятьИзИсточника = Истина) Экспорт Если РазрешитьМенятьИзИсточника Тогда СтрокаСопоставления.ИзИсточника = Колонка <> Неопределено; Если Не СтрокаСопоставления.ИзИсточника Тогда СтрокаСопоставления.Пометка = Ложь; КонецЕсли; КонецЕсли; Если Колонка <> Неопределено Тогда СтрокаСопоставления.ИмяКолонкиИсточника = Колонка.Имя; СтрокаСопоставления.СинонимКолонкиИсточника = Колонка.Заголовок; СтрокаСопоставления.ОписаниеТиповИсточника = Колонка.ТипЗначения; Иначе СтрокаСопоставления.ИмяКолонкиИсточника = ""; СтрокаСопоставления.СинонимКолонкиИсточника = ""; СтрокаСопоставления.ОписаниеТиповИсточника = Неопределено; КонецЕсли; КонецПроцедуры Процедура СопоставитьКолонкуТЗ(Знач СтрокаСопоставления, Знач Колонка = Неопределено, УстановитьДопСвойства = Истина) Экспорт Если Колонка <> Неопределено Тогда Если УстановитьДопСвойства Тогда СтрокаСопоставления.Пометка = Истина; Если СтрокаСопоставления.РежимКонвертации = "Устанавливать" Тогда СтрокаСопоставления.РежимКонвертации = "Искать"; КонецЕсли; КонецЕсли; СтрокаСопоставления.ИмяКолонкиИсточника = Колонка.Имя; СтрокаСопоставления.СинонимКолонкиИсточника = Колонка.Заголовок; СтрокаСопоставления.ПримерДанных = Колонка.ПримерДанных; Иначе Если СтрокаСопоставления.РежимКонвертации = "Искать" Тогда СтрокаСопоставления.РежимКонвертации = "Устанавливать"; КонецЕсли; СтрокаСопоставления.ИмяКолонкиИсточника = ""; СтрокаСопоставления.СинонимКолонкиИсточника = ""; СтрокаСопоставления.ПримерДанных = Неопределено; КонецЕсли; КонецПроцедуры Процедура ОчиститьСопоставлениеКолонокБД() Экспорт Для Каждого СтрокаКолонкиБД Из СопоставлениеКолонокБД Цикл СопоставитьКолонкуБД(СтрокаКолонкиБД); КонецЦикла; ОбновитьСопоставлениеКолонокБД(); КонецПроцедуры Процедура ОчиститьСопоставлениеКолонокТЗ() Экспорт Для Каждого СтрокаКолонкиТЗ Из СопоставлениеКолонокТЗ Цикл СопоставитьКолонкуТЗ(СтрокаКолонкиТЗ); КонецЦикла; ОбновитьСопоставлениеКолонокТЗ(); КонецПроцедуры Процедура ОбновитьСопоставлениеКолонокБД() Экспорт Для Каждого СтрокаКолонкиБД Из СопоставлениеКолонокБД Цикл Если Не СтрокаКолонкиБД.ИзИсточника Тогда Продолжить; КонецЕсли; Колонка = ТаблицаЗначений.Колонки.Найти(СтрокаКолонкиБД.ИмяКолонкиИсточника); СопоставитьКолонкуБД(СтрокаКолонкиБД, Колонка); КонецЦикла; КолонкиТЗ.Очистить(); Для Каждого Колонка Из ТаблицаЗначений.Колонки Цикл Если Ложь Или Колонка.Имя = мИмяКолонкиНомерСтроки Или ирОбщий.СтрКончаетсяНаЛкс(Колонка.Имя, мСуффиксСырыхДанных) Тогда Продолжить; КонецЕсли; СтрокаКолонки = КолонкиТЗ.Добавить(); СтрокаКолонки.ИмяКолонки = Колонка.Имя; СтрокаКолонки.СинонимКолонки = Колонка.Заголовок; СтрокаКолонки.ОписаниеТипов = Колонка.ТипЗначения; ИменаКолонокПриемника = СопоставлениеКолонокБД.Скопировать(Новый Структура("ИмяКолонкиИсточника", Колонка.Имя), "ИмяКолонкиПриемника").ВыгрузитьКолонку(0); СтрокаКолонки.КолонкиПриемника = ирОбщий.СтрСоединитьЛкс(ИменаКолонокПриемника); КонецЦикла; КонецПроцедуры Процедура ОбновитьСопоставлениеКолонокТЗ(УстановитьПометкуДляСопоставленных = Ложь, УстановитьПометкуДляНовых = Истина, ТолькоВыделенныеСтрокиТД = Ложь) Экспорт Для Каждого КолонкаТаблицы Из ТаблицаЗначений.Колонки Цикл Если Не ЗначениеЗаполнено(КолонкаТаблицы.Заголовок) Тогда КолонкаТаблицы.Заголовок = КолонкаТаблицы.Имя; КонецЕсли; КонецЦикла; КопияСопоставления = СопоставлениеКолонокТЗ.Скопировать(); СопоставлениеКолонокТЗ.Очистить(); КолонкиТабличногоДокумента = ПолучитьКолонкиТабличногоДокумента(, ТолькоВыделенныеСтрокиТД); Для Каждого Колонка Из ТаблицаЗначений.Колонки Цикл Если Ложь Или (Колонка.ТипЗначения.СодержитТип(Тип("ХранилищеЗначения")) И Колонка.ТипЗначения.Типы().Количество() = 1) Или (Колонка.ТипЗначения.СодержитТип(Тип("ТаблицаЗначений")) И Колонка.ТипЗначения.Типы().Количество() = 1) Или ирОбщий.СтрокиРавныЛкс(Колонка.Имя, мИмяКолонкиНомерСтроки) Или ирОбщий.СтрКончаетсяНаЛкс(Колонка.Имя, мСуффиксСырыхДанных) Тогда Продолжить; КонецЕсли; ЗагружаемыйРеквизит = СопоставлениеКолонокТЗ.Добавить(); ЗагружаемыйРеквизит.ИмяКолонкиПриемника = Колонка.Имя; ЗагружаемыйРеквизит.Пометка = УстановитьПометкуДляНовых; ЗагружаемыйРеквизит.СинонимКолонкиПриемника = Колонка.Заголовок; ЗагружаемыйРеквизит.ДоступноеОписаниеТипов = Колонка.ТипЗначения; ЗагружаемыйРеквизит.ОписаниеТипов = Колонка.ТипЗначения; СписокВыбора = ПолучитьСписокИменПредставлений(ЗагружаемыйРеквизит); ЗагружаемыйРеквизит.ИскатьПо = ?(СписокВыбора.Количество() = 0, "",СписокВыбора[0].Значение); СписокВыбора = ПолучитьСписокСвязейПоВладельцу(ЗагружаемыйРеквизит); ЗагружаемыйРеквизит.СвязьПоВладельцу = ?(СписокВыбора.Количество() = 0, "", СписокВыбора[0].Значение); СписокВыбора = ПолучитьСписокСвязейПоТипу(ЗагружаемыйРеквизит); Если СписокВыбора.Количество() = 0 Тогда ЗагружаемыйРеквизит.СвязьПоТипу = ""; ЗагружаемыйРеквизит.ЭлементСвязиПоТипу = 0; Иначе ЗагружаемыйРеквизит.СвязьПоТипу = СписокВыбора[0].Значение; Если Найти(ЗагружаемыйРеквизит.ИмяКолонкиПриемника, "3") <> 0 Тогда ЗагружаемыйРеквизит.ЭлементСвязиПоТипу = 3; ИначеЕсли Найти(ЗагружаемыйРеквизит.ИмяКолонкиПриемника, "2") <> 0 Тогда ЗагружаемыйРеквизит.ЭлементСвязиПоТипу = 2; Иначе ЗагружаемыйРеквизит.ЭлементСвязиПоТипу = 1; КонецЕсли; КонецЕсли; ЗагружаемыйРеквизит.Значение = ЗагружаемыйРеквизит.ОписаниеТипов.ПривестиЗначение(Неопределено); ЗагружаемыйРеквизит.РежимКонвертации = "Искать"; СтараяСтрока = КопияСопоставления.Найти(ЗагружаемыйРеквизит.ИмяКолонкиПриемника, "ИмяКолонкиПриемника"); Если СтараяСтрока <> Неопределено Тогда ЗаполнитьЗначенияСвойств(ЗагружаемыйРеквизит, СтараяСтрока,, "СинонимКолонкиПриемника, ОписаниеТипов, ДоступноеОписаниеТипов"); ПересечениеТипов = ирОбщий.ПересечьОписанияТиповЛкс(СтараяСтрока.ОписаниеТипов, ЗагружаемыйРеквизит.ОписаниеТипов,, 2); #Если Сервер И Не Сервер Тогда ПересечениеТипов = Новый ОписаниеТипов; #КонецЕсли Если ПересечениеТипов.Типы().Количество() > 0 Тогда ЗагружаемыйРеквизит.ОписаниеТипов = ПересечениеТипов; КонецЕсли; Если ЗагружаемыйРеквизит.РежимКонвертации = "Искать" Тогда СопоставитьКолонкуТЗ(ЗагружаемыйРеквизит, КолонкиТабличногоДокумента[СтараяСтрока.ИмяКолонкиИсточника], УстановитьПометкуДляСопоставленных); КонецЕсли; КонецЕсли; КонецЦикла; СопоставлениеКолонокТЗ.Сортировать("СинонимКолонкиПриемника"); Счетчик = 0; Для Каждого СтараяСтрока Из КопияСопоставления Цикл НоваяСтрока = СопоставлениеКолонокТЗ.Найти(СтараяСтрока.ИмяКолонкиПриемника, "ИмяКолонкиПриемника"); Если НоваяСтрока = Неопределено Тогда Продолжить; КонецЕсли; СопоставлениеКолонокТЗ.Сдвинуть(НоваяСтрока, Счетчик - СопоставлениеКолонокТЗ.Индекс(НоваяСтрока)); Счетчик = Счетчик + 1; КонецЦикла; //КолонкиТабличногоДокумента = ПолучитьКолонкиТабличногоДокумента(); Для Каждого СтрокаКолонкиТЗ Из СопоставлениеКолонокТЗ Цикл //Если Не СтрокаКолонкиТЗ.РежимКонвертации = "Искать" Тогда // Продолжить; //КонецЕсли; Если ЗначениеЗаполнено(СтрокаКолонкиТЗ.ИмяКолонкиИсточника) Тогда Колонка = КолонкиТабличногоДокумента[СтрокаКолонкиТЗ.ИмяКолонкиИсточника]; СопоставитьКолонкуТЗ(СтрокаКолонкиТЗ, Колонка, УстановитьПометкуДляСопоставленных); КонецЕсли; КонецЦикла; НесопоставленныеКолонкиТД.Очистить(); Для Каждого КлючИЗначение Из КолонкиТабличногоДокумента Цикл Колонка = КлючИЗначение.Значение; Если СопоставлениеКолонокТЗ.Найти(Колонка.Имя, "ИмяКолонкиИсточника") = Неопределено Тогда СтрокаКолонки = НесопоставленныеКолонкиТД.Добавить(); СтрокаКолонки.ИмяКолонки = Колонка.Имя; СтрокаКолонки.СинонимКолонки = Колонка.Заголовок; СтрокаКолонки.ПримерДанных = Колонка.ПримерДанных; КонецЕсли; КонецЦикла; НесопоставленныеКолонкиТД.Сортировать("СинонимКолонки"); КонецПроцедуры //ирПортативный лФайл = Новый Файл(ИспользуемоеИмяФайла); //ирПортативный ПолноеИмяФайлаБазовогоМодуля = Лев(лФайл.Путь, СтрДлина(лФайл.Путь) - СтрДлина("Модули\")) + "ирПортативный.epf"; //ирПортативный #Если Клиент Тогда //ирПортативный Контейнер = Новый Структура(); //ирПортативный Оповестить("ирПолучитьБазовуюФорму", Контейнер); //ирПортативный Если Не Контейнер.Свойство("ирПортативный", ирПортативный) Тогда //ирПортативный ирПортативный = ВнешниеОбработки.ПолучитьФорму(ПолноеИмяФайлаБазовогоМодуля); //ирПортативный ирПортативный.Открыть(); //ирПортативный КонецЕсли; //ирПортативный #Иначе //ирПортативный ирПортативный = ВнешниеОбработки.Создать(ПолноеИмяФайлаБазовогоМодуля, Ложь); // Это будет второй экземпляр объекта //ирПортативный #КонецЕсли //ирПортативный ирОбщий = ирПортативный.ПолучитьОбщийМодульЛкс("ирОбщий"); //ирПортативный ирКэш = ирПортативный.ПолучитьОбщийМодульЛкс("ирКэш"); //ирПортативный ирСервер = ирПортативный.ПолучитьОбщийМодульЛкс("ирСервер"); //ирПортативный ирПривилегированный = ирПортативный.ПолучитьОбщийМодульЛкс("ирПривилегированный"); мПлатформа = ирКэш.Получить(); мИмяКолонкиНомерСтроки = ирОбщий.ИмяКолонкиВнутреннегоИДСтрокиЛкс(); мИмяКолонкиРезультатПоиска = "_РезультатПоиска" + ирОбщий.СуффиксСлужебногоСвойстваЛкс(); мИмяКолонкиРезультатЗаписи = "_РезультатЗаписи" + ирОбщий.СуффиксСлужебногоСвойстваЛкс(); мИмяКолонкиСообщенияОбработки = "_Сообщения" + ирОбщий.СуффиксСлужебногоСвойстваЛкс(); мСуффиксСырыхДанных = "_Сырое" + ирОбщий.СуффиксСлужебногоСвойстваЛкс(); мЭтоСсылочныйОбъект = Ложь; //СтрокаЗаголовковТД = 1; //ПерваяСтрокаДанныхТД = 2; ВыводитьОшибкиКонвертацииСразу = Истина; ВыводитьОшибкаЗагрузкиСразу = Истина; ДобавлятьСтрокиБД = Истина; ОбновлятьСтрокиБД = Истина; ОтбиратьСразу = Истина; СвязиИПараметрыВыбора = Истина; ЭтотОбъект.КоличествоПотоков = 1; ЭтотОбъект.КоличествоОбъектовВПорции = 10; ЭтотОбъект.ВыполнятьНаСервере = ирОбщий.ПолучитьРежимОбъектыНаСервереПоУмолчаниюЛкс(Ложь); ПримитивныеТипы = Новый Структура; // Порядок важен! ПримитивныеТипы.Вставить("Число", Тип("Число")); ПримитивныеТипы.Вставить("Дата", Тип("Дата")); ПримитивныеТипы.Вставить("Булево", Тип("Булево")); ПримитивныеТипы.Вставить("Строка", Тип("Строка"));