Выбери документ - получи значения реквизитов! Печать
Автор: А.Волос   
06.03.2014 08:20

Предлагаю вниманию публики интересную на мой взгляд программу (1с внешняя обработка).

- выбираем из раскрывающего списка имя типа документа, программа помещает во второй раскрывающийся список номера всех документов выбранного типа.
- далее выбираем из второго списка номер конкретного документа выбранного типа, программа выводит имена и значения всех реквизитов табличных частей документа.
- вывод результата в табличное поле.

 

История:
Программист Alexander Speshilov написал несколько интересных функций (не помню точно имя сайта источника), результат работы которых: вывод имен всех реквизитов системы. В частности функция ПолучитьВсеХранимыеРеквизитыКонфигурации().

 

Эта великолепная функция выводит имена всех реквизитов всех документов. Взяв идею из этой функции переделаем код так, чтобы программа выводила ЗНАЧЕНИЯ реквизитов всех табличных частей выбранного пользователем из раскрывающегося списка документа.

 

Программа работает следующим образом:

 

1. Получает: имя документа, имена всех вкладок (табличных частей), имена всех реквизитов каждой вкладки.

 

Имея эти данные программа в цикле (по числу вкладок) формирует запрос к БД, используя имена вкладок и реквизитов, на предмет получения значений реквизитов.

 

Полученные в каждой итерации значения помещаются в таблицу значений, где колонками являются имена реквизитов, а строками - значения реквизитов. Если запрос вернул пустую таблицу, то программа заполняет поля ее прочерками.

 

Полученные таблицы в каждой итерации цикла складываются в структуру вида:

 

- имя документа
- имя табличной части
- таблица значений реквизитов

 

Затем эта структура укладывается в массив структур. Так пока не будут просканированы все табличные части документа.

 

Затем полученный таким образом массив обратно разворачивется в новую таблицу значений, нужного нам формата, и выводится в табличное поле!

 

Здесь демонстрируется несколько техник:

- функция автоматического создания запроса к БД по каждой в кладке.
- манипуляции с коллекциями
- предоставление пользователю доступа ко всем(!) документам системы
- связь таблицы значений и табличного поля

 

Скачать файл внешней обработки 1с "Выбери документ - получи значения реквизитов!":
Скачать

 

Код программы:

 

 

Функция ТЗПустыхРеквизитов3(СтруктураРеквизитов)
        
        ТЗДанных = Новый ТаблицаЗначений;

        Для Каждого Элемент из СтруктураРеквизитов Цикл 
                ТЗДанных.Колонки.Добавить(Элемент.Ключ,   Новый ОписаниеТипов("Строка"));
        КонецЦикла; 
        
        НовСтрока = ТЗДанных.Добавить();
        Для Каждого Элемент из СтруктураРеквизитов Цикл 
                НовСтрока[Элемент.Ключ] = "---";
        КонецЦикла; 
        
        
        Возврат ТЗДанных;
        
КонецФункции

Функция ЗаполняетТЗДанными(ПолнаяСтруктТабЧастей, ТЗРезультат)
        
        ИмяДок = "";
        ИмяТабЧасти = "";
        
        Инд = 0;
    Для Каждого Элемент из ПолнаяСтруктТабЧастей Цикл
                
            Если  СокрЛП(Элемент.Ключ) = "ТаблицаЗнач" Тогда

                        Количество = Элемент.Значение.Колонки.Количество();
                        Для каждого Строка из Элемент.Значение Цикл
                                Для Индекс = 0 По Количество-1 Цикл 

                                        НовСтрока = ТЗРезультат.Добавить();
                                        НовСтрока.Документ = ИмяДок;
                                        НовСтрока.ТабЧасть = ИмяТабЧасти;
                                        НовСтрока.Реквизит = Элемент.Значение.Колонки[Индекс].Имя;
                                        НовСтрока.ЗначениеРеквизита = Строка[СокрЛП(Элемент.Значение.Колонки[Индекс].Имя)];

                                        //Сообщить(СокрЛП(Индекс)+" "+СокрЛП(Элемент.Значение.Колонки[Индекс].Имя)+ ": " + Строка[СокрЛП(Элемент.Значение.Колонки[Индекс].Имя)]);
                                КонецЦикла;
                        КонецЦикла;
                        
                Иначе   

                                Если Инд > 0  Тогда
                                        ИмяТабЧасти = Элемент.Значение;
                                        Инд = 0;
                                Иначе 
                                        ИмяДок = Элемент.Значение;
                                КонецЕсли;      
                                //Сообщить(Элемент.Ключ + ": " + Элемент.Значение);
                КонецЕсли;      
                
                 Инд =  Инд+1;
    КонецЦикла; 
                         
КонецФункции    


// По переданной структуре полей формирует запрос по табличной части документа.
//
// Параметры: 
//  ДокументОбъект        - объект проводимого документа, 
//  ИмяТабличнойЧасти     - строка, имя табличной части,
//  СтруктураПолей        - структура, ключ структуры содержит псевдоним поля запроса, значение - строку запроса,
//  СтруктураСложныхПолей - структура, ключ структуры содержит псевдоним поля запроса, значение - строку запроса,
//                          необязательный параметр, служит для передачи конструкций типа "ВЫБОР" и т.д.
//
// Возвращаемое значение:
//  Результат запроса.
//
Функция мСформироватьЗапросПоТабличнойЧасти2(ДокументОбъект, ИмяТабличнойЧасти, СтруктураПолей,
                                           СтруктураСложныхПолей = Неопределено) Экспорт

        ТекстЗапроса = "";
        
        ДокументМетаданные = ДокументОбъект.Метаданные();

        Для Каждого Реквизит Из СтруктураПолей Цикл

                ТекстЗапроса  = ТекстЗапроса + ",
                |Док." + Реквизит.Значение + 
                " КАК " + СокрЛП(Реквизит.Ключ);

        КонецЦикла;
        
        ТекстСоединение="";
        
        Запрос = Новый Запрос;

        Если ТипЗнч(СтруктураСложныхПолей) = Тип("Структура") Тогда // Добавим к запросу конструкции.
                
                Для Каждого Элемент Из СтруктураСложныхПолей Цикл
                        
                        ТекстЗапроса  = ТекстЗапроса + ",
                        | " + Элемент.Значение + 
                        " КАК " + СокрЛП(Элемент.Ключ);
                        
                КонецЦикла;
                
                Если СтруктураСложныхПолей.Свойство("Проект") Тогда
                        
                        ТекстСоединение="
                        |ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.УстановкаПроектовДляНоменклатуры.СрезПоследних(&ДатаДок, НоменклатураПроекта В (ВЫБРАТЬ Номенклатура ИЗ Документ." + ДокументМетаданные.Имя + "."+ СокрЛП(ИмяТабличнойЧасти) + " ГДЕ Ссылка = &ДокументСсылка)) КАК ПроектыНоменклатуры
                        |ПО Док.Номенклатура=ПроектыНоменклатуры.НоменклатураПроекта";
                        
                        Запрос.УстановитьПараметр("ДатаДок",ДокументОбъект.Дата);
                КонецЕсли;
        КонецЕсли;
                
        Запрос.Текст = "ВЫБРАТЬ 
                                | Док.НомерСтроки " + ТекстЗапроса + "
                                | ИЗ 
                                |      Документ." + ДокументМетаданные.Имя + "."+ СокрЛП(ИмяТабличнойЧасти) + 
                                " КАК Док"+ТекстСоединение+" 
                                |     ГДЕ Док.Ссылка = &ДокументСсылка";


        // Установим параметры запроса.
        Запрос.УстановитьПараметр("ДокументСсылка" , ДокументОбъект.Ссылка);
        
        Если ДокументОбъект[ИмяТабличнойЧасти].Количество() = 0 Тогда
                //Запрос.Текст = СтрЗаменить(Запрос.Текст, "ГДЕ Док.Ссылка = &ДокументСсылка", "ГДЕ ЛОЖЬ");
        КонецЕсли;

        //Возврат Запрос.Выполнить();
        Возврат Запрос.Текст;
        
КонецФункции // СформироватьЗапросПоТабличнойЧасти()

// Функция "расщепляет" строку на подстроки, используя заданный 
//              разделитель. Разделитель может иметь любую длину. 
//              Если в качестве разделителя задан пробел, рядом стоящие пробелы 
//              считаются одним разделителем, а ведущие и хвостовые пробелы параметра Стр
//              игнорируются.
//              Например, 
//              РазложитьСтрокуВМассивПодстрок(",ку,,,му", ",") возвратит массив значений из пяти элементов, 
//              три из которых - пустые строки, а 
//              РазложитьСтрокуВМассивПодстрок(" ку   му", " ") возвратит массив значений из двух элементов
//
//      Параметры: 
//              Стр - строка, которую необходимо разложить на подстроки. 
//              Разделитель -   строка-разделитель, по умолчанию - запятая.
//
//      Возвращаемое значение:
//              массив значений, элементы которого - подстроки
//
Функция РазложитьСтрокуВМассив(Знач Стр, Разделитель = ",") Экспорт
        
        МассивСтрок = Новый Массив();
        Если Разделитель = " " Тогда
                Стр = СокрЛП(Стр);
                Пока 1=1 Цикл
                        Поз = Найти(Стр,Разделитель);
                        Если Поз=0 Тогда
                                МассивСтрок.Добавить(Стр);
                                Возврат МассивСтрок;
                        КонецЕсли;
                        МассивСтрок.Добавить(Лев(Стр,Поз-1));
                        Стр = СокрЛ(Сред(Стр,Поз));
                КонецЦикла;
        Иначе
                ДлинаРазделителя = СтрДлина(Разделитель);
                Пока 1=1 Цикл
                        Поз = Найти(Стр,Разделитель);
                        Если Поз=0 Тогда
                                МассивСтрок.Добавить(Стр);
                                Возврат МассивСтрок;
                        КонецЕсли;
                        МассивСтрок.Добавить(Лев(Стр,Поз-1));
                        Стр = Сред(Стр,Поз+ДлинаРазделителя);
                КонецЦикла;
        КонецЕсли;
        
КонецФункции    

// Разворачивает массив строк через РазвернутьСтрокуОбходаМетаданных
//
// Параметры
//  МассивСтрокОбхода  - Массив - Массив разворачиваемых строк
//  ЗаменяемоеЗначение  - Строка - заменяемое значение
//  ПредставлениеПоУмолчанию - Строка - выражение для получения представления
//
// Возвращаемое значение:
//   Массив строк
//
Функция РазвернутьМассивСтрокОбходаМетаданных(МассивСтрокОбхода, ЗаменяемоеЗначение = "*", ПредставлениеПоУмолчанию = "Имя")
    
    Рез = Новый Массив;
    
    Для каждого СтрокаОбхода Из МассивСтрокОбхода Цикл
        
        ДополнениеРезультата = РазвернутьСтрокуОбходаМетаданных(СтрокаОбхода, ЗаменяемоеЗначение, ПредставлениеПоУмолчанию);
        Для каждого ТекСтрока Из ДополнениеРезультата Цикл
            Рез.Добавить(ТекСтрока);
        КонецЦикла; 
        
    КонецЦикла; 
    
    Возврат Рез;
    
КонецФункции // РазвернутьМассивСтрокОбходаМетаданных()

// Преобразует строку в массив одиночных строк по разделителю Символы.ПС
//
// Параметры
//  ПреобразуемаяСтрока - строка для преобразования
//    ИгнорироватьПустые - Булево - Пропускать пустые строки
//  СокращатьПробелы - Использовать СокрЛП
//
// Возвращаемое значение:
//   Массив строк
//
Функция ПолучитьМассивСтрокМногострочнойСтроки(ПреобразуемаяСтрока, ИгнорироватьПустые = Истина, СокращатьПробелы = Истина)
    
    Рез = Новый Массив;
    ЧислоСтрок = СтрЧислоСтрок(ПреобразуемаяСтрока);
    
    Для Сч = 1 По ЧислоСтрок Цикл
        
        ТекСтрока = СтрПолучитьСтроку(ПреобразуемаяСтрока, Сч);
        Если ИгнорироватьПустые и ПустаяСтрока(ТекСтрока) Тогда
            Продолжить;
        КонецЕсли; 
        Если СокращатьПробелы Тогда
            ТекСтрока = СокрЛП(ТекСтрока);
        КонецЕсли; 
        Рез.Добавить(ТекСтрока);
        
    КонецЦикла;
    
    Возврат Рез;
    
КонецФункции // ПолучитьМассивСтрокМногострочнойСтроки()

// Рекурсивная функция, которая разворачивает строку вида "Метаданные.Справочники.*[Имя].Реквизиты.*.Тип" 
// в массив строк, заменяя "*" или другой символ, задаваемый параметрами обходом всех элементов 
// коллекции. Допускает выполнение функций встроенного языка (не стоит отдавать ввод параметров 
// пользователям). При этом выражение, используемое для получения по умолчанию может быть задано в 
// квадратных скобках или параметром функции.
//
// Параметры
//  СтрокаОбхода  - Строка - Разворачиваемая строка
//  ЗаменяемоеЗначение  - Строка - заменяемое значение
//  ПредставлениеПоУмолчанию - Строка - выражение для получения представления
//
// Возвращаемое значение:
//   Массив строк
//
Функция РазвернутьСтрокуОбходаМетаданных(СтрокаОбхода, ЗаменяемоеЗначение = "*", ПредставлениеПоУмолчанию = "")
    
    Рез = Новый Массив;
    
    ЧастиСтрокиОбхода = РазобратьСтрокуОбхода(СтрокаОбхода, ЗаменяемоеЗначение, ПредставлениеПоУмолчанию);
    Если ЧастиСтрокиОбхода = Неопределено тогда 
        Рез.Добавить(СтрокаОбхода); //фактически это ограничение рекурсии.
    Иначе
        ОбъектКоллекции = Вычислить(ЧастиСтрокиОбхода.СтрокаКоллекции);
                
        РазвернутаяКоллекция = РазвернутьКоллекциюВПредставления(ОбъектКоллекции, ЧастиСтрокиОбхода.СтрокаПредставление);
                индекс = 0;
        Для каждого ЭлементРазвернутойКоллекции Из РазвернутаяКоллекция Цикл
            
            // рекурсивный вызов
            ТекущаяСтрокаОбхода = ЧастиСтрокиОбхода.СтрокаНачало + ЭлементРазвернутойКоллекции + ЧастиСтрокиОбхода.СтрокаКонец;
                        
                        индекс = индекс+1;
                        
            МассивЭлемента = РазвернутьСтрокуОбходаМетаданных(ТекущаяСтрокаОбхода, ЗаменяемоеЗначение, ПредставлениеПоУмолчанию);
            
            Для каждого ПримитивныйЭлементОбхода Из МассивЭлемента Цикл
                Рез.Добавить(ПримитивныйЭлементОбхода);
            КонецЦикла;
            
        КонецЦикла;
    КонецЕсли;
    
    Возврат Рез;
    
КонецФункции // РазвернутьСтрокуОбходаМетаданных()

// Разбирает строку обхода на удобные для работы поля
//
// Параметры
//  СтрокаОбхода  - Строка - Разворачиваемая строка
//  ЗаменяемоеЗначение  - Строка - заменяемое значение
//  ПредставлениеПоУмолчанию - Строка - выражение для получения представления
//
// Возвращаемое значение:
//   Структура с полями ПозицияЗамены, СтрокаНачало, СтрокаКоллекции, СтрокаПредставление, СтрокаКонец
// или Неопределено (если строка не содержит ЗаменяемоеЗначение)
//
Функция РазобратьСтрокуОбхода(СтрокаОбхода, ЗаменяемоеЗначение, ПредставлениеПоУмолчанию)
    
    Если ПустаяСтрока(ЗаменяемоеЗначение) Тогда 
        ВызватьИсключение "Некорректное выражение заменяемого значения";
    КонецЕсли;
    
    ПозицияЗамены = Найти(СтрокаОбхода, ЗаменяемоеЗначение);
    
    // Если не найдена строка - возвращаем неопределено, как индикатор
    Если ПозицияЗамены = 0 Тогда 
        Возврат Неопределено; 
    КонецЕсли;
    
    СтрокаНачало = Лев(СтрокаОбхода,ПозицияЗамены - 1);
    
    //Получение строки для выражения-коллекции
    СтрокаКоллекции = СтрокаНачало;
    Если Прав(СтрокаКоллекции, 1) = "." Тогда 
        СтрокаКоллекции = Лев(СтрокаКоллекции,СтрДлина(СтрокаКоллекции) - 1);
    КонецЕсли;
    
    ПозицияОкончанияЗамены = ПозицияЗамены + СтрДлина(ЗаменяемоеЗначение);
    
    ОстатокВыражения = Сред(СтрокаОбхода, ПозицияОкончанияЗамены);
    
    //Обработка явного задания представления
    ОткрывающаяСкобка = "[";
    ЗакрывающаяСкобка = "]";
    Если Найти(ОстатокВыражения, ОткрывающаяСкобка) = 1 Тогда
        ОстатокВыражения = Сред(ОстатокВыражения, СтрДлина(ОткрывающаяСкобка) + 1);
        ПозицияЗакрывающейСкобки = Найти(ОстатокВыражения, ЗакрывающаяСкобка);
        Если ПозицияЗакрывающейСкобки = 0 Тогда 
            ВызватьИсключение "Синтаксическая ошибка разбора выражения";
        КонецЕсли;
        СтрокаПредставление = Лев(ОстатокВыражения, ПозицияЗакрывающейСкобки - 1);
        ОстатокВыражения = Сред(ОстатокВыражения, ПозицияЗакрывающейСкобки + СтрДлина(ЗакрывающаяСкобка));
    Иначе
        СтрокаПредставление = ПредставлениеПоУмолчанию;
    КонецЕсли;
    СтрокаКонец = ОстатокВыражения;
    
    Рез = Новый Структура("ПозицияЗамены, СтрокаНачало, СтрокаКоллекции, СтрокаПредставление, СтрокаКонец",
    ПозицияЗамены, СтрокаНачало, СтрокаКоллекции, СтрокаПредставление, СтрокаКонец);
    
    Возврат Рез;
    
КонецФункции // РазобратьСтрокуОбхода()


функция СсылкаНаДокумент(ТипДок, Номер)
        
        Запрос = Новый Запрос();
        Запрос.УстановитьПараметр("Номер", Номер);

        Запрос.Текст = 
        "ВЫБРАТЬ
        |       "+ТипДок+".Ссылка
        |ИЗ
        |       Документ."+ТипДок+" КАК "+ТипДок+"
        |ГДЕ
        |       "+ТипДок+".Номер = &Номер";
        
        Док = Запрос.Выполнить().Выбрать();
                
        Пока Док.Следующий() Цикл
            ДокументОснование = Док.Ссылка;
            //Сообщить("Ссылка: "      + ДокументОснование);
        КонецЦикла;     
                
                Возврат ДокументОснование;
        
КонецФункции

// Разворачивает объект коллекции в массив представления элементов
//
// Параметры
//  Коллекция  - Произвольный - Коллекция, которую можно обойти через "Для каждого"
//  ПредставлениеЭлемента  - Строка - необяз., свойство элементов коллекции, которое 
//               используется для получения представления.
//
// Возвращаемое значение:
//   Массив   - Массив представлений коллекции
//
Функция РазвернутьКоллекциюВПредставления(Коллекция, Знач ПредставлениеЭлемента = "")
        
        Колво = Коллекция.Количество();
        
    //Проверка и подгонка параметров
    Если не ПустаяСтрока(ПредставлениеЭлемента) Тогда 
        Если Найти(ПредставлениеЭлемента, ";")>0 Тогда 
            ВызватьИсключение "Некорректное выражение представления";
        КонецЕсли;
        ПредставлениеЭлемента = "." + ПредставлениеЭлемента;
    КонецЕсли;
        
    Рез = Новый Массив;
        
    Для каждого ЭлементКоллекции Из Коллекция Цикл
        ТекПредставление = Строка(Вычислить("ЭлементКоллекции" + ПредставлениеЭлемента));
        Рез.Добавить(ТекПредставление);
    КонецЦикла; 
        
    Возврат Рез;
    
КонецФункции // РазвернутьКоллекцию()

// Проверяет используется ли в Объекте указанный общий реквизит
//
Функция ИспользуетсяОбщийРеквизит(ОбщийРеквизит, Объект) Экспорт

    Если ТипЗнч(Объект) = Тип("ОбъектМетаданных") Тогда
        МетаданныеОбъекта = Объект;
    Иначе
        МетаданныеОбъекта = Метаданные.НайтиПоТипу(ТипЗнч(Объект));
        Если МетаданныеОбъекта = Неопределено Тогда
            Возврат Ложь;
        КонецЕсли;
    КонецЕсли;

    Если ТипЗнч(ОбщийРеквизит) = Тип("ОбъектМетаданных") Тогда
        МетаданныеОбщегоРеквизита = ОбщийРеквизит;
    Иначе
        МетаданныеОбщегоРеквизита = Метаданные.ОбщиеРеквизиты.Найти(ОбщийРеквизит);
        Если МетаданныеОбщегоРеквизита = Неопределено Тогда
            Возврат Ложь;
        КонецЕсли;
    КонецЕсли;

    ЭлементСостава = МетаданныеОбщегоРеквизита.Состав.Найти(МетаданныеОбъекта);

    Если ЭлементСостава = Неопределено Тогда
        Возврат Ложь;
    КонецЕсли;

    пИспользованиеОбщегоРеквизита = Метаданные.СвойстваОбъектов.ИспользованиеОбщегоРеквизита;

    Если ЭлементСостава.Использование = пИспользованиеОбщегоРеквизита.Использовать Тогда
        Возврат Истина;
    иначеЕсли ЭлементСостава.Использование = пИспользованиеОбщегоРеквизита.НеИспользовать Тогда
        Возврат Ложь;
    Иначе
        пАвтоИспользованиеОбщегоРеквизита = Метаданные.СвойстваОбъектов.АвтоИспользованиеОбщегоРеквизита;

        Если МетаданныеОбщегоРеквизита.АвтоИспользование = пАвтоИспользованиеОбщегоРеквизита.Использовать Тогда
            Возврат Истина;
        Иначе
            Возврат Ложь;
        КонецЕсли;
    КонецЕсли;

КонецФункции

//возвращает булево
//если флаг=1 то ТЗ не пуста
//если флаг=0 то ТЗ пуста
Функция НеПустаяТЗ(Элемент)
        
        Количество = Элемент.Колонки.Количество();
        флаг = 0;
        Для каждого Строка из Элемент Цикл
                Для Индекс = 0 По Количество-1 Цикл 
                        флаг = 1;
                        break;
                КонецЦикла;
        КонецЦикла;
                        
        Если флаг > 0 Тогда
                 Возврат флаг;
        Иначе
                 Возврат флаг;
        КонецЕсли;      
КонецФункции    



Процедура КнопкаВыполнитьНажатие(Кнопка)
        
        ТипДокумента = ЭлементыФормы.ПолеВыбора2.Значение;
        НомерДок     = ЭлементыФормы.ПолеВыбора1.Значение;
        
        Если СокрЛП(ТипДокумента) = "" Тогда
                Предупреждение("Выберите тип документа");
        ИначеЕсли  СокрЛП(НомерДок) = "" Тогда
                Предупреждение("Выберите номер документа");
        Иначе   
                
                ДокСсылка = СсылкаНаДокумент(ТипДокумента, НомерДок);
                ДокОбъект = ДокСсылка.ПолучитьОбъект();
                
                
                //Создадим таблицу значений и заполним ее
                ТЗДанных = Новый ТаблицаЗначений;
                ТЗДанных.Колонки.Добавить("Документ",   Новый ОписаниеТипов("Строка"));
                ТЗДанных.Колонки.Добавить("ТабЧасть",   Новый ОписаниеТипов("Строка"));
                ТЗДанных.Колонки.Добавить("Реквизит",   Новый ОписаниеТипов("Строка"));
                ТЗДанных.Колонки.Добавить("ЗначениеРеквизита",  Новый ОписаниеТипов("Строка"));
                
                нТипДокумента  = СокрЛП(ТипДокумента);
                
                СтрокаВсехРеквизитов = 
                "
                |Метаданные.Документы." + нТипДокумента + ".ТабличныеЧасти.*.Реквизиты.*
                |";
        
                МассивСтрокМногострочнойСтроки = ПолучитьМассивСтрокМногострочнойСтроки(СтрокаВсехРеквизитов);
                
                мМассивСтрок = РазвернутьМассивСтрокОбходаМетаданных(МассивСтрокМногострочнойСтроки, "*", "Имя");
                
                Для Каждого эл Из мМассивСтрок Цикл
                        МасСтрок = РазложитьСтрокуВМассив(эл, ".");
                        НоваяСтрока = ТЗДанных.Добавить();
                        НоваяСтрока.Документ = СокрЛП(МасСтрок[2]);
                        НоваяСтрока.ТабЧасть = СокрЛП(МасСтрок[4]);
                        НоваяСтрока.Реквизит = СокрЛП(МасСтрок[6]);
                        НоваяСтрока.ЗначениеРеквизита = "Знач. Реквизита";
                        
                КонецЦикла;             

                //Инициируем табличное поле данными из таблицы значений
                //ТабличноеПоле1 = ТЗДанных;

                КолонкиТЗ = ТЗДанных.Колонки;
                
                МассивРеквиз          = Новый Массив;
                МассивТабЧастей       = Новый Массив;

                МассивРеквиз.Добавить(ТЗДанных.ВыгрузитьКолонку(КолонкиТЗ[2] ));
                МассивТабЧастей.Добавить(ТЗДанных.ВыгрузитьКолонку(КолонкиТЗ[1] ));

                МасТемп               = новый Массив();
                МасНовыхСтруктур      = Новый Массив();
                МасВременный          = новый Массив();

                СтрТемп               = "";
                колич = МассивРеквиз[0].Количество();
                
                //Просканируем массив таб частей 
                индМассивТабЧастей = 0;
                Для Каждого элем Из МассивТабЧастей Цикл
                        Для Каждого элл Из элем Цикл
                                
                                Если индМассивТабЧастей = 0 Тогда
                                        СтрТемп = элл;
                                КонецЕсли;      
                                
                                
                                Если СтрТемп <> элл ИЛИ индМассивТабЧастей > колич-2 Тогда    //если строки не равны или это последний элемент массива
                                        
                                        Если индМассивТабЧастей > колич-2 Тогда
                                                МасТемп.Добавить(МассивРеквиз[0][индМассивТабЧастей]);
                                        КонецЕсли;      
                                        
                                        //Сообщить("СтрТемп: "+СтрТемп+" элл: "+ элл);

                                        // Получим необходимые данные для проведения и проверки заполнения данных по табличной части "Товары".
                                        СтруктураПолей = Новый Структура();
                                        
                                        Для Каждого Элемент из МасТемп Цикл 
                                                СтруктураПолей.Вставить(Элемент, Элемент);
                                        КонецЦикла; 
                                        
                                        //СканПростойСтруктуры(СтруктураПолей);
                                        
                                        Запрос = Новый Запрос;
                                        Запрос.УстановитьПараметр("ДокументСсылка", ДокСсылка);
                                        
                                        Запрос.Текст = мСформироватьЗапросПоТабличнойЧасти2(ДокОбъект, СтрТемп, СтруктураПолей);

                                        ТаблицаЗнач = Запрос.Выполнить().Выгрузить(); 
                                                                                
                                                                                
                                Если НеПустаяТЗ(ТаблицаЗнач)  Тогда
                                                                                
                                                                                        
                                        МасВременный = ТаблицаЗнач.Скопировать(); //Скопируем во временный массив ТЗ
                                        //ПоказатьТаблицу(ТаблицаЗнач);

                                        //Создадим структуру, в которой сохраним эту таблицу значений.
                                        СтруктураТабЧасти           = Новый Структура (); 

                                        //Добавим в структуру еще один элемент ключ:имя таб части, значение:индекс
                                        СтруктураТабЧасти.Вставить("ИмяДокумента", ТипДокумента);
                                        СтруктураТабЧасти.Вставить("ИмяТабЧасти", СтрТемп);
                                        СтруктураТабЧасти.Вставить("ТаблицаЗнач", МасВременный);

                                        //Показать структуру для проверки
                                        //СканСтруктурыСодержащейТЗ(СтруктураТабЧасти);

                                        МасНовыхСтруктур.Добавить(СтруктураТабЧасти);
                                                                                        
                                Иначе
                                                                                
                                        //СканПростойСтруктуры(СтруктураПолей);
                                        ТаблицаЗначЗЗЗ = ТЗПустыхРеквизитов3(СтруктураПолей);
                                        //ПоказатьТаблицу(ТаблицаЗначЗЗЗ);
                                                                                        
                                        МасВременный = ТаблицаЗначЗЗЗ.Скопировать(); //Скопируем во временный массив ТЗ

                                        //Создадим структуру, в которой сохраним эту таблицу значений.
                                        СтруктураТабЧасти           = Новый Структура (); 

                                        //Добавим в структуру еще один элемент ключ:имя таб части, значение:индекс
                                        СтруктураТабЧасти.Вставить("ИмяДокумента", ТипДокумента);
                                        СтруктураТабЧасти.Вставить("ИмяТабЧасти", СтрТемп);
                                        СтруктураТабЧасти.Вставить("ТаблицаЗнач", МасВременный);

                                        //Показать структуру для проверки
                                        //СканСтруктурыСодержащейТЗ(СтруктураТабЧасти);

                                        МасНовыхСтруктур.Добавить(СтруктураТабЧасти);
                                                                                        
                                КонецЕсли;      
                                                                                
                                МасТемп.Очистить();
                                СтрТемп = элл;
                                        
                                Если индМассивТабЧастей > колич-2 Тогда
                                        break;  
                                КонецЕсли;      
                                        
                                КонецЕсли;
                                
                                МасТемп.Добавить(МассивРеквиз[0][индМассивТабЧастей]);
                                
                                индМассивТабЧастей = индМассивТабЧастей+1;
                        КонецЦикла;
                КонецЦикла;
                                
                ТЗРезультат = Новый ТаблицаЗначений;
                ТЗРезультат.Колонки.Добавить("Документ",            Новый ОписаниеТипов("Строка"));
                ТЗРезультат.Колонки.Добавить("ТабЧасть",            Новый ОписаниеТипов("Строка"));
                ТЗРезультат.Колонки.Добавить("Реквизит",            Новый ОписаниеТипов("Строка"));
                ТЗРезультат.Колонки.Добавить("ЗначениеРеквизита",   Новый ОписаниеТипов("Строка"));

                Для Каждого ЭлементМас из МасНовыхСтруктур Цикл 
                        ЗаполняетТЗДанными(ЭлементМас, ТЗРезультат);
                КонецЦикла; 

                //Инициируем табличное поле данными из таблицы значений
                ТабличноеПоле1 = ТЗРезультат;
                                
                                
        КонецЕсли;                      
КонецПроцедуры 

Процедура ПриОткрытииФормы()
        
        Для Каждого Документ Из Метаданные.Документы Цикл
                //Проверим, есть ли права на просмотр? Да- добавляем, Нет - пропускаем
                Если ПравоДоступа("Просмотр", Документ) Тогда
                        ИмяДокумента = Документ.Имя;
                        ЭлементыФормы.ПолеВыбора2.СписокВыбора.Добавить(ИмяДокумента, ИмяДокумента);
                КонецЕсли;
        КонецЦикла;  
        
КонецПроцедуры



Процедура Кнопка2_ВыполнитьНажатие(Элемент)
        
    ТипДокумента = ЭлементыФормы.ПолеВыбора2.Значение;
        
        Если СокрЛП(ТипДокумента) = "" Тогда
        Предупреждение("Выберите тип документа");
                
        Иначе   
                
                ЭлементыФормы.ПолеВыбора1.СписокВыбора.Очистить();
                //Выведем список номеров документов данного типа
                Запрос = Новый Запрос; 
                Запрос.Текст = ("ВЫБРАТЬ "+ТипДокумента+".Ссылка,"+ТипДокумента+".Номер ИЗ Документ."+ТипДокумента+" КАК "+ТипДокумента); 

                Результат = Запрос.Выполнить(); 
                Выборка = Результат.Выбрать(); 
                Пока Выборка.Следующий() Цикл 
                        ЭлементыФормы.ПолеВыбора1.СписокВыбора.Добавить(Выборка.Номер,Выборка.Номер) ;  
                КонецЦикла; 
        
        КонецЕсли;
        
КонецПроцедуры


Процедура ПриИзмененииПолеВыбора2(Элемент)
        
    ТипДокумента = ЭлементыФормы.ПолеВыбора2.Значение;
        
        Если СокрЛП(ТипДокумента) = "" Тогда
                   Предупреждение("Выберите тип документа");
        Иначе   
                ЭлементыФормы.ПолеВыбора1.СписокВыбора.Очистить();
                //Выведем список номеров документов данного типа
                Запрос = Новый Запрос; 
                Запрос.Текст = ("ВЫБРАТЬ "+ТипДокумента+".Ссылка,"+ТипДокумента+".Номер ИЗ Документ."+ТипДокумента+" КАК "+ТипДокумента); 

                Результат = Запрос.Выполнить(); 
                
                Выборка = Результат.Выбрать(); 
                Пока Выборка.Следующий() Цикл 
                        ЭлементыФормы.ПолеВыбора1.СписокВыбора.Добавить(Выборка.Номер,Выборка.Номер) ;  
                КонецЦикла; 
        
        КонецЕсли;
        
КонецПроцедуры


 

Скачать файл внешней обработки 1с "Выбери документ - получи значения реквизитов!":
Скачать

 

Обновлено 23.09.2014 16:17