//******************************************************************************
Функция глМод(числ) Экспорт //возвращает значения числа "по модулю"
Возврат ?(числ<0,-числ,числ);
КонецФункции
//******************************************************************************
// глЭлементОчереди(Знач Очередь,Знач Разделитель, Знач Позиция)
Функция глЭлементОчереди(Знач Очередь, Знач Разделитель, Знач Позиция) Экспорт
Если ПустаяСтрока(Очередь)=1 Тогда
Возврат "";
КонецЕсли;
Если СтрЧислоВхождений(Очередь,Разделитель)<Позиция-1 Тогда
Возврат "";
КонецЕсли;
ДлинаРазделителя = СтрДлина(Разделитель)-1;
Пока Позиция>1 Цикл
Позиция = Позиция-1;
ПозицияРазделителя = Найти(Очередь,Разделитель);
Очередь = Прав(Очередь,СтрДлина(Очередь)-ПозицияРазделителя-ДлинаРазделителя);
КонецЦикла;
Если СтрЧислоВхождений(Очередь,Разделитель)=0 Тогда
Возврат Очередь;
КонецЕсли;
Возврат Лев(Очередь,Найти(Очередь,Разделитель)-1);
КонецФункции
//******************************************************************************
Функция глВнутреннийИдентификатор(Объект) Экспорт
ТипОбъекта = ТипЗначенияСтр(Объект);
Если Найти("Строка,Число,Дата",ТипОбъекта) > 0 Тогда
Возврат СокрЛП(Строка(Объект));
ИначеЕсли ТипОбъекта = "Справочник" Тогда
ВнутреннееПредставление = ЗначениеВСтрокуВнутр(Объект.ТекущийЭлемент());
ИначеЕсли ТипОбъекта = "Документ" Тогда
ВнутреннееПредставление = ЗначениеВСтрокуВнутр(Объект.ТекущийДокумент());
Иначе
ВнутреннееПредставление = ЗначениеВСтрокуВнутр(Объект);
КонецЕсли;
ВнутреннееПредставление = СтрЗаменить(СтрЗаменить(ВнутреннееПредставление,"{",""),"}","");
Идентификатор = СокрЛП(СтрЗаменить(глЭлементОчереди(ВнутреннееПредставление,",",7),"""",""));
Если Найти(Идентификатор," ") > 0 Тогда
// если идентификатор содержит в себе идентификатор вида,
// то последний отсекается, нужен только идентификатор объекта
Идентификатор = СокрЛП(Сред(Идентификатор,Найти(Идентификатор," ")));
КонецЕсли;
Возврат СокрЛП(_IdToStr(Идентификатор));
КонецФункции // глВнутреннийИдентификатор
//******************************************************************************
Функция глИзТЗ(тз,СтрокаТЗ=0,КолонкаТЗ) Экспорт
СтрокаТЗ = ?(СтрокаТЗ=0,тз.НомерСтроки,СтрокаТЗ);
Попытка
Возврат тз.ПолучитьЗначение(СтрокаТЗ,КолонкаТЗ);
Исключение
Сообщить(ОписаниеОшибки()+"; Строка: " + СтрокаТЗ + "/" + тз.КоличествоСтрок()+"; колонка: "+КолонкаТЗ,"!!");
Возврат 0;
КонецПопытки;
КонецФункции // ПолучитьЗначениеИзТЗ
//******************************************************************************
//Множитель: 0 - заменить значение, 1 - Прибавить к значению, -1 - вычесть из значения
Процедура глВТЗ(тз,СтрокаТЗ=0,КолонкаТЗ,ЗначениеТЗ,Множитель=0) Экспорт
СтрокаТЗ = ?(СтрокаТЗ=0,тз.НомерСтроки,СтрокаТЗ);
Попытка
зн = ?(ТипЗначенияСтр(ЗначениеТЗ)="Число",?(Множитель=0,ЗначениеТЗ,глИзТЗ(тз,СтрокаТЗ,КолонкаТЗ)+ЗначениеТЗ*Множитель),ЗначениеТЗ);
тз.УстановитьЗначение(СтрокаТЗ,КолонкаТЗ,зн);
Исключение
Сообщить(ОписаниеОшибки()+"; Строка: " + СтрокаТЗ + "/" + тз.КоличествоСтрок()+"; колонка: "+КолонкаТЗ+"; ("+ЗначениеТЗ+"*["+Множитель+"])","!!");
КонецПопытки;
КонецПроцедуры // УстановитьВТЗ
//******************************************************************************
Функция глПечатьТЗ(тз,Показать=0) Экспорт
Т = СоздатьОбъект("Таблица");
Т.ИсходнаяТаблица("ТЗ");
зн = "";
Т.ВывестиСекцию("Заголовок|Начало");
Для а = 1 По тз.КоличествоКолонок() Цикл
зн = тз.ПолучитьПараметрыКолонки(а);
Т.ПрисоединитьСекцию("Заголовок|Колонка");
КонецЦикла;
тз.ВыбратьСтроки();
Пока тз.ПолучитьСтроку() = 1 Цикл
Т.ВывестиСекцию("Строка|Начало");
Для а = 1 По тз.КоличествоКолонок() Цикл
зн = глИзТЗ(тз,,тз.ПолучитьПараметрыКолонки(а));
Если СокрЛП(Строка(Число(зн))) = СокрЛП(Строка(зн)) Тогда
зн = Формат(зн,"Ч0.,");
ИначеЕсли ТипЗначенияСтр(зн) = "Справочник" Тогда
Если зн.Вид() = "ГотоваяПродукция" Тогда
зн = зн.Код + " " + зн.Наименование;
КонецЕсли;
КонецЕсли;
Т.ПрисоединитьСекцию("Строка|Колонка");
КонецЦикла;
КонецЦикла;
Т.ТолькоПросмотр(1);
Если Показать = 1 Тогда
Т.Показать();
КонецЕсли;
Возврат Т;
КонецФункции // глПечатьТЗ
//******************************************************************************
// Заполняет значения параметров приёмника значениями источника, определяя по имени
// Параметры:
// -Приемник - ТаблицаЗначений,СписокЗначений,ГрупповойКонтекст,Документ или Справочник, значения которого нужно заполнить
// -Источник - ТаблицаЗначений,СписокЗначений,ГрупповойКонтекст,Документ или Справочник, откуда значения нужно взять
// -ТолькоСвойства - строка с именами свойств через запятую. Если задана, то заполняются только указанные свойства
// Возможно переопределение имен свойств используя знак равенства, например: "Клиент=Контрагент"
// Слева от знака "=" имя свойства получателя, справа - источника
// -ИсключаяСвойства - строка с именами свойств через запятую. Если задана, то указанные свойства заполнятся не будут
// Если в предидущем параметре было задано переопределение имен, то указывается свойство Приемника
Процедура глЗаполнитьЗначения(Приемник,Источник,Знач ТолькоСвойства="",Знач ИсключаяСвойства="") Экспорт
ДопустимыеТипы = "ТаблицаЗначений,СписокЗначений,ГрупповойКонтекст,Документ,Справочник";
ТипИсточника = ТипЗначенияСтр(Источник);
ТипПриемника = ТипЗначенияСтр(Приемник);
Если Найти(ДопустимыеТипы,ТипИсточника) = 0 Тогда
Сообщить("глЗаполнитьЗначения::Недопустимый тип источника");
Возврат;
ИначеЕсли Найти(ДопустимыеТипы,ТипПриемника) = 0 Тогда
Сообщить("глЗаполнитьЗначения::Недопустимый тип приемника");
Возврат;
КонецЕсли;
// обрамление фильтров запятыми, чтобы имя "Сумма" не обнаруживалось в именах типа "СуммаНДС, СуммаСписать или СуммаНачисления"
ТолькоСвойства = ?(ПустаяСтрока(ТолькоСвойства) =1,"",","+СтрЗаменить(ТолькоСвойства ," ","")+",");
ИсключаяСвойства = ?(ПустаяСтрока(ИсключаяСвойства)=1,"",","+СтрЗаменить(ИсключаяСвойства," ","")+",");
//{ Для простоты дальнейшей обработки конвертация источника в список значений
сзИсточник = СоздатьОбъект("СписокЗначений");
Если ТипИсточника = "СписокЗначений" Тогда
Для а = 1 По Источник.РазмерСписка() Цикл
ИмяСвойства = "";
ЗначениеСвойства = Источник.ПолучитьЗначение(а,ИмяСвойства);
ИмяСвойства = ?(ПустаяСтрока(ИмяСвойства)=1,"Значение"+а,ИмяСвойства);
сзИсточник.Установить(ИмяСвойства,ЗначениеСвойства);
КонецЦикла;
ИначеЕсли ТипИсточника = "ТаблицаЗначений" Тогда
Если Источник.НомерСтроки = 0 Тогда
Сообщить("глЗаполнитьЗначения::Нет позиционирования на строку в источнике");
Возврат;
КонецЕсли;
Для а = 1 По Источник.КоличествоКолонок() Цикл
ИмяСвойства = Источник.ПолучитьПараметрыКолонки(а);
сзИсточник.Установить(ИмяСвойства,Источник.ПолучитьЗначение(Источник.НомерСтроки,ИмяСвойства));
КонецЦикла;
Иначе // Документ, Справочник или ГрупповойКонтекст, который тоже может быть справочником или документов
ВидИсточника = Источник.Вид();
Если Метаданные.Документ(ВидИсточника).Выбран() = 1 Тогда
Для а = 1 По Метаданные.Документ(ВидИсточника).РеквизитШапки() Цикл
ИмяСвойства = Метаданные.Документ(ВидИсточника).РеквизитШапки(а).Идентификатор;
сзИсточник.Установить(ИмяСвойства,Источник.ПолучитьАтрибут(ИмяСвойства));
КонецЦикла;
Для а = 1 По Метаданные.ОбщийРеквизитДокумента() Цикл
ИмяСвойства = Метаданные.ОбщийРеквизитДокумента(а).Идентификатор;
сзИсточник.Установить(ИмяСвойства,Источник.ПолучитьАтрибут(ИмяСвойства));
КонецЦикла;
Для а = 1 По Метаданные.Документ(ВидИсточника).РеквизитТабличнойЧасти() Цикл
ИмяСвойства = Метаданные.Документ(ВидИсточника).РеквизитТабличнойЧасти(а).Идентификатор;
сзИсточник.Установить(ИмяСвойства,Источник.ПолучитьАтрибут(ИмяСвойства));
КонецЦикла;
ИначеЕсли Метаданные.Справочник(ВидИсточника).Выбран() = 1 Тогда
Для а = 1 По Метаданные.Справочник(ВидИсточника).Реквизит() Цикл
ИмяСвойства = Метаданные.Справочник(ВидИсточника).Реквизит(а).Идентификатор;
сзИсточник.Установить(ИмяСвойства,Источник.ПолучитьАтрибут(ИмяСвойства));
КонецЦикла;
Иначе
Сообщить("глЗаполнитьЗначения::Недопустимый вид источника");
КонецЕсли;
КонецЕсли;
//}
//{ Заполнение списка значений приемника полученными значениями, попутно фильтруя и конвертируя
Если (ПустаяСтрока(ТолькоСвойства)=0) или (ПустаяСтрока(ИсключаяСвойства)=0) Тогда
сзПриемник = СоздатьОбъект("СписокЗначений");
Если ПустаяСтрока(ТолькоСвойства)=0 Тогда
Если Найти(ТолькоСвойства,"=")=0 Тогда
Для а = 1 По сзИсточник.РазмерСписка() Цикл
ИмяСвойства = "";
ЗначениеСвойства = сзИсточник.ПолучитьЗначение(а,ИмяСвойства);
Если Найти(ТолькоСвойства,","+ИмяСвойства+",") > 0 Тогда
Если Найти(ИсключаяСвойства,","+ИмяСвойства+",") = 0 Тогда
сзПриемник.Установить(ИмяСвойства,ЗначениеСвойства);
КонецЕсли;
КонецЕсли;
КонецЦикла;
Иначе // Имеется переопределение имен свойств, обработка более сложная
КоличествоЗначений = СтрЧислоВхождений(ТолькоСвойства,",")-1; // Строка обрамлена запятыми
Для а = 2 По КоличествоЗначений Цикл
ИмяСвойства = глЭлементОчереди(ТолькоСвойства,",",а);
Если Найти(ИмяСвойства,"=") = 0 Тогда
Если Найти(ИсключаяСвойства,","+ИмяСвойства+",")=0 Тогда
сзПриемник.Установить(ИмяСвойства,сзИсточник.Получить(ИмяСвойства));
КонецЕсли;
Иначе
Если Найти(ИсключаяСвойства,","+глЭлементОчереди(ИмяСвойства,"=",1)+",")=0 Тогда
сзПриемник.Установить(глЭлементОчереди(ИмяСвойства,"=",1),сзИсточник.Получить(глЭлементОчереди(ИмяСвойства,"=",2)));
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Иначе
Для а = 1 По сзИсточник.РазмерСписка() Цикл
ИмяСвойства = "";
ЗначениеСвойства = сзИсточник.ПолучитьЗначение(а,ИмяСвойства);
Если Найти(ИсключаяСвойства,","+ИмяСвойства+",") = 0 Тогда
сзПриемник.Установить(ИмяСвойства,ЗначениеСвойства);
КонецЕсли;
КонецЦикла;
КонецЕсли;
Иначе // Нет никаких фильтров, приемник равен источнику
сзПриемник = сзИсточник;
КонецЕсли;
//}
//{ Конвертация списка значений в указанный тип
Если ТипПриемника = "СписокЗначений" Тогда
Для а = 1 По сзПриемник.РазмерСписка() Цикл
ИмяСвойства = "";
ЗначениеСвойства = сзПриемник.ПолучитьЗначение(а,ИмяСвойства);
Приемник.Установить(ИмяСвойства,ЗначениеСвойства);
КонецЦикла;
ИначеЕсли ТипПриемника = "ТаблицаЗначений" Тогда
Если Приемник.НомерСтроки = 0 Тогда
Сообщить("глЗаполнитьЗначения::Нет позиционирования на строку в приемнике");
Возврат;
КонецЕсли;
Для а = 1 По сзПриемник.РазмерСписка() Цикл
ИмяСвойства = "";
ЗначениеСвойства = сзПриемник.ПолучитьЗначение(а,ИмяСвойства);
Если Приемник.ВидимостьКолонки(ИмяСвойства) > -1 Тогда
Приемник.УстановитьЗначение(Приемник.НомерСтроки,ИмяСвойства,ЗначениеСвойства);
КонецЕсли;
КонецЦикла;
Иначе
Попытка
Для а = 1 По сзПриемник.РазмерСписка() Цикл
ИмяСвойства = "";
ЗначениеСвойства = сзПриемник.ПолучитьЗначение(а,ИмяСвойства);
Приемник.УстановитьАтрибут(ИмяСвойства,ЗначениеСвойства);
КонецЦикла;
Исключение
Сообщить("глЗаполнитьЗначения::Ошибка при попытке установки значения в атрибут """+ИмяСвойства+"""::"+ОписаниеОшибки());
Возврат;
КонецПопытки;
КонецЕсли;
//}
КонецПроцедуры // глЗаполнитьЗначения
//******************************************************************************
// метод сделан на скорую руку и предполагает, что в ИмяРеквизита могут подать максимум формулу,
// а не кашу из спец. символолов в разных кодировках. Кроме того, метод пока не умеет корректно
// отрабатывать строки состоящие только из цифр и пустые строки, потому, что в таком случае нужно
// придумывать альтернативное уникальное имя, что на данном этапе разработки невозможно
Функция глКорректноеИмяРеквизита(Знач ИмяРеквизита,Знач НедопустимыеСимволы=".[]()/*-+%") Экспорт
Для а = 1 По СтрДлина(НедопустимыеСимволы) Цикл
ИмяРеквизита = СтрЗаменить(ИмяРеквизита,Сред(НедопустимыеСимволы,а,1),"");
КонецЦикла;
Возврат ИмяРеквизита;
КонецФункции // глКорректноеИмяРеквизита
//******************************************************************************
// Функкция предназначена для добавления колонки в переданную таблицу значений и заполнения значением
// Значение можно передавать формулой, но к формуле довольно жёсткие требования:
// 1. Формула должна быть заключена в квадратные кавычки, т.к. для её вычисления используется функция Шаблон
// 2. В формуле можно использовать только примитивные типы или значения самой таблицы
// 3. К значениям таблицы обращаться только через имя "тз"
// 4. Результат функции всегда строка, поэтому для неявного преобразования к другому примитивному типу нужно указывать Тип
// Значение можно передавать как реквизит другого значения таблицы, требования:
// 1. Значение передается без квадратных кавычек
// 2. Значение указывается через точку и без имени таблицы (Например: ГП.Код)
// 3. Значение должно быть только одно, формула не сработает
Процедура глДобавитьКолонкуВТаблицу(тз,Знач ИмяКолонки,Тип="",Длина="",Точность="",ЗначениеКолонки="") Экспорт
Перем зн;
Если ТипЗначенияСтр(тз) <> "ТаблицаЗначений" Тогда
Сообщить("глДобавитьКолонкуВТаблицу::не задана таблица значений::Параметры:ИмяКолонки="+ИмяКолонки+",Тип="""+Тип+""",Длина="+Число(Длина)+",Точность="+Число(Точность)+",Значение="+ЗначениеКолонки,"!!");
Возврат;
КонецЕсли;
Если СтрЧислоВхождений(ИмяКолонки,",") > 0 Тогда
Для а = 1 По СтрЧислоВхождений(ИмяКолонки,",")+1 Цикл
глДобавитьКолонкуВТаблицу(тз,глЭлементОчереди(ИмяКолонки,",",а),Тип,Длина,Точность,ЗначениеКолонки);
КонецЦикла;
Возврат;
КонецЕсли;
ИмяКолонки = глКорректноеИмяРеквизита(ИмяКолонки);
Если тз.ВидимостьКолонки(ИмяКолонки) < 0 Тогда
Попытка
тз.НоваяКолонка(ИмяКолонки,Тип,Длина,Точность);
Исключение
Сообщить("глДобавитьКолонкуВТаблицу::Ошибка добавления колонки ("+ИмяКолонки+")::"+ОписаниеОшибки(),"!!");
Возврат;
КонецПопытки;
КонецЕсли;
Если тз.КоличествоСтрок() > 0 Тогда
Если ПустоеЗначение(ЗначениеКолонки) = 0 Тогда
Если ТипЗначенияСтр(ЗначениеКолонки)="Строка" Тогда
Если СтрЧислоВхождений(ЗначениеКолонки,"[") > 0 Тогда
тз.ВыбратьСтроки();
Пока тз.ПолучитьСтроку() = 1 Цикл
глВТЗ(тз,,ИмяКолонки,Шаблон(ЗначениеКолонки));
КонецЦикла;
ИначеЕсли СтрЧислоВхождений(ЗначениеКолонки,".") > 0 Тогда
тз.ВыбратьСтроки();
Пока тз.ПолучитьСтроку() = 1 Цикл
зн = "";
Шаблон("[глПрисвоить(зн,"+?(Лев(ЗначениеКолонки,3)="тз.","","тз.")+ЗначениеКолонки+")]");
глВТЗ(тз,,ИмяКолонки,зн);
КонецЦикла;
ИначеЕсли тз.ВидимостьКолонки(ЗначениеКолонки) <> -1 Тогда
тз.ВыбратьСтроки();
Пока тз.ПолучитьСтроку() = 1 Цикл
зн = "";
Шаблон("[глПрисвоить(зн,тз."+ЗначениеКолонки+")]");
глВТЗ(тз,,ИмяКолонки,зн);
КонецЦикла;
Иначе
тз.Заполнить(ЗначениеКолонки,,,ИмяКолонки);
КонецЕсли;
Иначе
тз.Заполнить(ЗначениеКолонки,,,ИмяКолонки);
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры // глДобавитьКолонкуВТаблицу
//******************************************************************************
// Функция позволяет получить таблицу значений из документа, запроса или другой таблицы значений
// Параметры:
// Источник - Документ, Запрос или ТаблицаЗначений
//
// СписокКолонок - Строка с именами колонок через запятую. Разрешается:
// - Использовать идентификатор реквизита табличной части документа или колонки таблицы значений
// Например: тз = глВзятьТаблицу(СсылкаНаДокумент,"ГП,Сумма")
// - Использовать идентификатор реквизита шапки документа
// Например: тз = глВзятьТаблицу(СсылкаНаДокумент,"Контрагент,ГП,Сумма")
// - Обращаться к свойствам других колонок через точку, имя колонки сгенерируется автоматически
// Например: тз = глВзятьТаблицу(СсылкаНаДокумент,"ГП,тз.ГП.Код") // имя второй колонки = "тзГПКод"
// обращение к таблице значений ("тз.") можно не указывать
// Например: тз = глВзятьТаблицу(СсылкаНаДокумент,"ГП,ГП.Код") // имя второй колонки = "ГПКод"
// - Вызывать стандартные методы значений таблицы
// Например: тз = глВзятьТаблицу(СсылкаНаДокумент,"ГП,ГП.Вид()") // имя второй колонки = "ГПВид"
// - Явно указывать имя колонки таблицы
// Например: тз = глВзятьТаблицу(СсылкаНаДокумент,"ГП,Вид=ГП.Вид()")
// тз = глВзятьТаблицу(СсылкаНаДокумент,"ГП,Цена=ОтпускнаяЦена")
// Зарезервированные имена:
// - ДатаДок - Дата переданного документа
// - НомерДок - Номер переданного документа
// - Ссылка - Ссылка на переданный документ
// - НомерСтроки - Номер строки табличной части переданного документа
//
// Фильтр - Список значений, где:
// Представление - имя колонки
// Значение - Значение в этой колонке
//
Функция глВзятьТаблицу(Знач Источник,Знач СписокКолонок="",Знач Фильтр="") Экспорт
Тип = ТипЗначенияСтр(Источник);
Если ПустаяСтрока(СписокКолонок) = 0 Тогда
СписокКолонок = СтрЗаменить(СписокКолонок," ","");
КонецЕсли;
Если Тип = "ТаблицаЗначений" Тогда
Результат = СоздатьОбъект("ТаблицаЗначений");
Результат.Загрузить(Источник);
Если ПустаяСтрока(СписокКолонок) = 0 Тогда
ЧислоКолонок = СтрЧислоВхождений(СписокКолонок,",")+1;
Для а = 1 По ЧислоКолонок Цикл
ИмяКолонки = глЭлементОчереди(СписокКолонок,",",а);
Если Результат.ВидимостьКолонки(ИмяКолонки) < 0 Тогда
Если Найти(ИмяКолонки,"=") = 0 Тогда
Если (СтрЧислоВхождений(ИмяКолонки,".")=0) и (СтрЧислоВхождений(ИмяКолонки,"[")=0) Тогда
глДобавитьКолонкуВТаблицу(Результат,ИмяКолонки);
Иначе
глДобавитьКолонкуВТаблицу(Результат,ИмяКолонки,,,,ИмяКолонки);
КонецЕсли;
Иначе // Например: ВидГП=ГП.Вид()
глДобавитьКолонкуВТаблицу(Результат,глЭлементОчереди(ИмяКолонки,"=",1),,,,глЭлементОчереди(ИмяКолонки,"=",2));
СписокКолонок=СтрЗаменить(СписокКолонок,ИмяКолонки,глЭлементОчереди(ИмяКолонки,"=",1));
КонецЕсли;
КонецЕсли;
КонецЦикла;
// Удаление лишних колонок + упорядочивание
тзВрем = СоздатьОбъект("ТаблицаЗначений");
Результат.Выгрузить(тзВрем,,,глКорректноеИмяРеквизита(СписокКолонок));
Результат = тзВрем;
КонецЕсли;
Если ТипЗначенияСтр(Фильтр) = "СписокЗначений" Тогда
ОтсутствующиеКолонки = "";
Для а = 1 По Фильтр.РазмерСписка() Цикл
ИмяКолонки = "";
Значение = Фильтр.ПолучитьЗначение(а,ИмяКолонки);
Если Результат.ВидимостьКолонки(ИмяКолонки) < 0 Тогда
ОтсутствующиеКолонки = ОтсутствующиеКолонки + ","+ИмяКолонки;
КонецЕсли;
КонецЦикла;
Если ПустаяСтрока(ОтсутствующиеКолонки) = 0 Тогда
Сообщить("глВзятьТаблицу::Ошибка применения фильтра::Отсутствуют колонки: "+Сред(ОтсутствующиеКолонки,2),"!!");
Результат = "";
Иначе
КоличествоСтрок = Результат.КоличествоСтрок();
Для а = 1 По КоличествоСтрок Цикл
ТекСтрока = КоличествоСтрок - а + 1;
Для аа = 1 По Фильтр.РазмерСписка() Цикл
ИмяКолонки = "";
Значение = Фильтр.ПолучитьЗначение(аа,ИмяКолонки);
Если глИзТЗ(Результат,ТекСтрока,ИмяКолонки) <> Значение Тогда
Результат.УдалитьСтроку(ТекСтрока);
Прервать;
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецЕсли;
КонецЕсли;
ИначеЕсли Тип = "Запрос" Тогда
Попытка
Результат = СоздатьОбъект("ТаблицаЗначений");
Источник.Выгрузить(Результат,1,0);
Результат = глВзятьТаблицу(Результат,СписокКолонок,Фильтр);
Исключение
Сообщить("глВзятьТаблицу::Ошибка выгрузки результата запроса ("+СписокКолонок+")::"+ОписаниеОшибки(),"!!");
Результат = "";
КонецПопытки;
ИначеЕсли (Тип = "Документ") или (Тип = "ГрупповойКонтекст") Тогда
Если Источник.Вид() = "СБ03_СчетФактура" Тогда
// у него нет своей табличной части, нужно использовать таблицу из основания - счета
ИсточникТаблицы = Источник.осн;
Иначе
ИсточникТаблицы = Источник;
КонецЕсли;
МетаданныеДокумента = Метаданные.Документ(ИсточникТаблицы.Вид());
Если МетаданныеДокумента.РеквизитТабличнойЧасти() = 0 Тогда
Сообщить("глВзятьТаблицу::Документ "+ИсточникТаблицы.ПредставлениеВида()+" не имеет табличной части","!!");
Результат = "";
Иначе
Попытка
Результат = СоздатьОбъект("ТаблицаЗначений");
Если ПустаяСтрока(СписокКолонок) = 0 Тогда
РеквизитыТаблицы = "";
ЧислоКолонок = СтрЧислоВхождений(СписокКолонок,",")+1;
Для а = 1 По ЧислоКолонок Цикл
ИмяРеквизита = глЭлементОчереди(СписокКолонок,",",а);
ИмяРеквизита = ?(Найти(ИмяРеквизита,"=")=0,ИмяРеквизита,глЭлементОчереди(ИмяРеквизита,"=",2));
Если МетаданныеДокумента.РеквизитТабличнойЧасти(ИмяРеквизита).Выбран() = 1 Тогда
РеквизитыТаблицы = РеквизитыТаблицы + "," + ИмяРеквизита;
ИначеЕсли ИмяРеквизита = "НомерСтроки" Тогда
РеквизитыТаблицы = РеквизитыТаблицы + "," + ИмяРеквизита;
КонецЕсли;
КонецЦикла;
Если ПустаяСтрока(РеквизитыТаблицы) = 0 Тогда
РеквизитыТаблицы = Сред(РеквизитыТаблицы,2);
ИсточникТаблицы.ВыгрузитьТабличнуюЧасть(Результат,РеквизитыТаблицы);
Иначе
// Не сказали что грузить, грузим все колонки
ИсточникТаблицы.ВыгрузитьТабличнуюЧасть(Результат);
КонецЕсли;
МетаданныеДокумента = Метаданные.Документ(Источник.Вид()); // Реквизиты Шапки всегда источника, а не источника таблицы
Для а = 1 По ЧислоКолонок Цикл
ИмяРеквизита = глЭлементОчереди(СписокКолонок,",",а);
ИмяРеквизита = ?(Найти(ИмяРеквизита,"=")=0,ИмяРеквизита,глЭлементОчереди(ИмяРеквизита,"=",2));
Если МетаданныеДокумента.РеквизитШапки(ИмяРеквизита).Выбран() = 1 Тогда
глДобавитьКолонкуВТаблицу(Результат,ИмяРеквизита,,,,Источник.ПолучитьАтрибут(ИмяРеквизита));
ИначеЕсли Найти("номердок,датадок",НРег(ИмяРеквизита)) > 0 Тогда
глДобавитьКолонкуВТаблицу(Результат,ИмяРеквизита,,,,Источник.ПолучитьАтрибут(ИмяРеквизита));
ИначеЕсли НРег(ИмяРеквизита) = "ссылка" Тогда
глДобавитьКолонкуВТаблицу(Результат,"Ссылка","Документ."+Источник.Вид(),,,Источник.ТекущийДокумент());
КонецЕсли;
КонецЦикла;
Иначе
ИсточникТаблицы.ВыгрузитьТабличнуюЧасть(Результат);
КонецЕсли;
Результат = глВзятьТаблицу(Результат,СписокКолонок,Фильтр);
Исключение
Сообщить("глВзятьТаблицу::Ошибка получения таблицы из документа ("+СписокКолонок+")::"+ОписаниеОшибки());
Результат = "";
КонецПопытки;
КонецЕсли;
Иначе
Результат = "";
КонецЕсли;
Если ТипЗначенияСтр(Результат) <> "ТаблицаЗначений" Тогда
// Функция должна вернуть таблицу значений указанной структуры в любом случае
// если информации нет, то нужно создать пустую таблицу
Результат = СоздатьОбъект("ТаблицаЗначений");
Если ПустаяСтрока(СписокКолонок) = 0 Тогда
ЧислоКолонок = СтрЧислоВхождений(СписокКолонок,",")+1;
Если ЧислоКолонок > 0 Тогда
Для а = 1 По ЧислоКолонок Цикл
глДобавитьКолонкуВТаблицу(Результат,глЭлементОчереди(СписокКолонок,",",а));
КонецЦикла;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции // глВзятьТаблицу
//******************************************************************************
Функция глСписокКолонок(Знач Источник,Исключения="") Экспорт
Источник = глВзятьТаблицу(Источник);
Результат = "";
Для а = 1 По Источник.КоличествоКолонок() Цикл
ИмяКолонки = Источник.ПолучитьПараметрыКолонки(а);
Если Найти(","+СокрЛП(Исключения)+",",","+ИмяКолонки+",") = 0 Тогда
Результат = Результат + "," + ИмяКолонки;
КонецЕсли;
КонецЦикла;
Возврат Сред(Результат,2);
КонецФункции // глКолонкиТаблицы
//******************************************************************************
Функция глИндексированнаяТаблица(тз,КлючевыеПоля,ИмяПоля="Индекс") Экспорт
Если ТипЗначенияСтр(тз) <> "ТаблицаЗначений" Тогда
Сообщить("глИндексированнаяТаблица::Ошибка при передаче параметров::Переданное значение не является таблицой значений");
Возврат тз;
КонецЕсли;
Если ПустаяСтрока(КлючевыеПоля) = 1 Тогда
Сообщить("глИндексированнаяТаблица::Ошибка при передаче параметров::Список индексируемых полей пуст");
Возврат тз;
КонецЕсли;
Формула = "";
Для а = 1 по СтрЧислоВхождений(КлючевыеПоля,",")+1 Цикл
Имя = глЭлементОчереди(КлючевыеПоля,",",а);
Если тз.ВидимостьКолонки(Имя) < 0 Тогда
Сообщить("глИндексированнаяТаблица::Ошибка при передаче параметров::Отсутствует поле '"+Имя+"'");
Возврат тз;
КонецЕсли;
Формула=Формула+"""#""+глВнутреннийИдентификатор(тз."+Имя+")";
КонецЦикла;
Результат = глВзятьТаблицу(тз);
глДобавитьКолонкуВТаблицу(Результат,ИмяПоля,"Строка",,,"["+Сред(Формула,3)+"]");
Возврат Результат;
КонецФункции // глТаблицаСИндексом
//******************************************************************************
Функция глСоединитьТаблицы(Знач тз1,тз2) Экспорт
Если ТипЗначенияСтр(тз1) <> "ТаблицаЗначений" Тогда
тз1 = СоздатьОбъект("ТаблицаЗначений");
КонецЕсли;
Если ТипЗначенияСтр(тз2) <> "ТаблицаЗначений" Тогда
Возврат тз1;
ИначеЕсли тз2.КоличествоКолонок() = 0 Тогда
Возврат тз1;
Иначе
// Колонки могут быть в другом порядке, тогда возникает неприятность
// Поэтому вторая таблица приводится к виду первой
тз2 = глВзятьТаблицу(тз2,глСписокКолонок(тз1));
КонецЕсли;
тз1.КоличествоСтрок(тз1.КоличествоСтрок()+тз2.КоличествоСтрок());
тз1.Заполнить(тз2,тз1.КоличествоСтрок()-тз2.КоличествоСтрок()+1);
Возврат тз1;
КонецФункции // глСоединитьТаблицы
//******************************************************************************
// Результат функции - таблица значений с аналогичной структурой, дополненной числовой колонкой
// КоэффициентУникальности, содержащей -1 или 1 - значения из тз1 и тз2 соответственно
//
// КлючевыеПоля - Список колонок, по которым необходимо сравнить таблицы, если не указаны, то все
Функция глРазличияТаблиц(Знач тз1,Знач тз2,Знач КлючевыеПоля="") Экспорт
тз1 = глВзятьТаблицу(тз1,КлючевыеПоля);
тз2 = глВзятьТаблицу(тз2,КлючевыеПоля);
Если ПустоеЗначение(КлючевыеПоля) = 1 Тогда
КлючевыеПоля = глСписокКолонок(тз1,"НомерСтрокиДокумента");
КонецЕсли;
глДобавитьКолонкуВТаблицу(тз1,"КоэффициентУникальности","Число",,,-1);
глДобавитьКолонкуВТаблицу(тз2,"КоэффициентУникальности","Число",,, 1);
тз = глСоединитьТаблицы(тз1,тз2);
тз.Свернуть(КлючевыеПоля,"КоэффициентУникальности");
КоличествоСтрок = тз.КоличествоСтрок();
Для а = 1 По КоличествоСтрок Цикл
ТекСтрока = КоличествоСтрок-а+1;
Если глИзТЗ(тз,ТекСтрока,"КоэффициентУникальности") = 0 Тогда
тз.УдалитьСтроку(ТекСтрока);
КонецЕсли;
КонецЦикла;
Возврат тз;
КонецФункции // глРазличияТаблиц
//******************************************************************************
// тз - Таблица значений
// СуммаРаспределения - Сумма, которую необходимо распределить
// КолонкаБазы - Название колонки, пропорционально чему распределять
// Колонка - Название колонки, куда поместить результат распределения
// ВариантУчетаПогрешности - Число:
// 0 - в строку с наибольшим удельным весом в базе распределения
// 1 - в первую строку
// 2 - в последнюю строку
Процедура глРаспределитьПропорционально(тз,КолонкаБазы,Колонка,СуммаРаспределения,ВариантУчетаПогрешности=0,Длина="",Точность="") Экспорт
Если тз.ВидимостьКолонки(Колонка) < 0 Тогда
тз.НоваяКолонка(Колонка,"Число",Длина,Точность);
КонецЕсли;
Если СуммаРаспределения = 0 Тогда Возврат; КонецЕсли;
БазаРаспределения = тз.Итог(КолонкаБазы);
Если БазаРаспределения = 0 Тогда Возврат; КонецЕсли;
МаксСтрока = 0;
МаксКоэффициент = 0;
тз.ВыбратьСтроки();
Пока тз.ПолучитьСтроку() = 1 Цикл
Коэффициент = глИзТЗ(тз,,КолонкаБазы)/БазаРаспределения;
Если Коэффициент <> 0 Тогда
глВТЗ(тз,,Колонка,СуммаРаспределения*Коэффициент);
Если ВариантУчетаПогрешности = 0 Тогда
Если глМод(Коэффициент) > глМод(МаксКоэффициент) Тогда
МаксКоэффициент = Коэффициент;
МаксСтрока = тз.НомерСтроки;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если тз.Итог(Колонка) <> СуммаРаспределения Тогда
Если ВариантУчетаПогрешности <> 0 Тогда
МаксСтрока = ?(ВариантУчетаПогрешности=1,1,тз.КоличествоСтрок());
КонецЕсли;
глВТЗ(тз,МаксСтрока,Колонка,СуммаРаспределения-тз.Итог(Колонка),1);
КонецЕсли;
КонецПроцедуры // РаспределитьПропорционально
//******************************************************************************
// Создает список значений, используется для быстрого создания списка параметров, необходимого для передачи между формами
// Параметры:
// - ИменаПараметров - Строка с именами параметров через запятую
// - Значение1,...,Значение10 - Значения параметров
Функция глПараметры(Знач ИменаПараметров,Значение1="",Значение2="",Значение3="",Значение4="",Значение5="",Значение6="",Значение7="",Значение8="",Значение9="",Значение10="") Экспорт
Результат = СоздатьОбъект("СписокЗначений");
ИменаПараметров = СтрЗаменить(ИменаПараметров," ","");
Для а = 1 По СтрЧислоВхождений(ИменаПараметров,",")+1 Цикл
зн = "";
Если а < 11 Тогда
Шаблон("[глПрисвоить(зн,Значение"+а+")]");
КонецЕсли;
Результат.Установить(глЭлементОчереди(ИменаПараметров,",",а),зн);
КонецЦикла;
Возврат Результат;
КонецФункции // глПараметры
//******************************************************************************
// глВыбратьЗначение(СписокЗначений, СпособВыбора=1, ЗначениеПоУмолчанию="",Заголовок="") Экспорт
// Описание: Возвращает результат выбора из переданного списка значений.
// В отличии от типового выбора не открывает выбор из одного значения, а сразу возвращает единственный вариант
// Параметры: СписокЗначений - из какого списка производится выбор
// СпособВыбора - соответствует значениям типовому методу списка значений,
// однако, значение по-умолчанию - 1 (в виде меню)
// ЗначениеПоУмолчанию - без комментариев
// Заголовок - что спросить в заголовке при способе выбора = 0
Функция глВыбратьЗначение(СписокЗначений, СпособВыбора=1, ЗначениеПоУмолчанию="",Заголовок="") Экспорт
Перем Результат, зн;
Результат = ЗначениеПоУмолчанию;
Если СписокЗначений.РазмерСписка() > 0 Тогда
Если СписокЗначений.РазмерСписка() = 1 Тогда
Результат = СписокЗначений.ПолучитьЗначение(1);
ИначеЕсли СписокЗначений.ВыбратьЗначение(зн,Заголовок,,80,СпособВыбора) = 1 Тогда
Результат = зн;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции // глВыбратьЗначение()
//******************************************************************************
Функция глТекущееЗначение(СписокЗначений,Позиция=0) Экспорт
ТекЗначение = СписокЗначений.ПолучитьЗначение(СписокЗначений.ТекущаяСтрока());
Если Позиция > 0 Тогда
СписокЗначений.ТекущаяСтрока(Позиция);
КонецЕсли;
Возврат ТекЗначение;
КонецФункции // глТекущееЗначение
//******************************************************************************
Функция глПомеченныеЗначения(СписокСПометками) Экспорт
Перем Представление;
сзРезультат = СоздатьОбъект("СписокЗначений");
Для а = 1 По СписокСПометками.РазмерСписка() Цикл
Если СписокСПометками.Пометка(а) = 1 Тогда
зн = СписокСПометками.ПолучитьЗначение(а,Представление);
сзРезультат.ДобавитьЗначение(зн,Представление);
КонецЕсли;
КонецЦикла;
Возврат сзРезультат;
КонецФункции // глПомеченныеЗначения