================================================================= СЕРВИСНЫЕ ФУНКЦИИ ДЛЯ ПОСТРОЕНИЯ СЛОЖНЫХ ОТЧЁТОВ (с) 2001 koeniger ---- http://koenigsoft.boom.ru/1s_repacc.htm http://www.hare.ru/kb/article.shtml?016 ================================================================= Функция ТЗНовая() Экспорт Далее //Создает новую пустую таблицу значений Процедура ТЗУстановить(Т, Стр, Кол="", Зн=0) Экспорт Далее //Устанавливает в таблице Т в строку Стр и колонку Кол значение Зн //Если колонки нет, она создается Функция ТЗПолучить(Т, Стр, Кол="") Экспорт Далее //Получает значение из таблицы Т в строке Стр и колонке Кол //Если значения нет, возвращает 0 Процедура ТЗВнести(Т, Кол1="", Зн1=0, Кол2="", Зн2=0, Кол3="", Зн3=0, Кол4="", Зн4=0, Кол5="", Зн5=0 , Кол6="", Зн6=0, Кол7="", Зн7=0, Кол8="", Зн8=0, Кол9="", Зн9=0, Кол10="", Зн10=0) Экспорт Далее //Вносит в таблицу Т сразу несколько значений в несколько колонок в новую строку Процедура ТЗИндексация(Т) Экспорт Далее //Подготавливает таблицу Т для поиска по нескольким строкам //После индексации таблицу нельзя изменять Функция ТЗПоискПер(Т, Колонка, флСумма=0, Кол1="", Зн1=0, Кол2="", Зн2=0, Кол3="", Зн3=0, Кол4="", Зн4=0, Кол5="", Зн5=0, Кол6="", Зн6=0, Кол7="", Зн7=0, Кол8="", Зн8=0, Кол9="", Зн9=0, Кол10="", Зн10=0) Экспорт Далее //Возвращаем в таблице значений Т Колонку, в которой значения в колонках Кол1, ... равны Зн1 ... //Если установлен флаг Суммы, то суммируется сразу по всем колонкам, где есть эти условия //Поиск осуществляется методом перебора и не требует индексации Функция ТЗПоиск(Т, Колонка, флСумма=0, Кол1="", Зн1=0, Кол2="", Зн2=0, Кол3="", Зн3=0, Кол4="", Зн4=0, Кол5="", Зн5=0, Кол6="", Зн6=0, Кол7="", Зн7=0, Кол8="", Зн8=0, Кол9="", Зн9=0, Кол10="", Зн10=0) Экспорт Далее //Возвращаем в таблице значений Т Колонку, в которой значения в колонках Кол1, ... равны Зн1 ... //Если установлен флаг Суммы, то суммируется сразу по всем колонкам, где есть эти условия //Поиск осуществляется быстрым поиском и требует предварительной индексации таблицы Исходные тексты функций Функция ТЗНовая() Экспорт Т=СоздатьОбъект("ТаблицаЗначений"); Возврат Т; КонецФункции Процедура ТЗУстановить(Т, Стр, Кол="", Зн=0) Экспорт Если Кол<>"" Тогда Попытка Т.УстановитьЗначение(Стр,Кол,Зн); Исключение Т.НоваяКолонка(Кол); Т.УстановитьЗначение(Стр,Кол,Зн); КонецПопытки; КонецЕсли; КонецПроцедуры Функция ТЗПолучить(Т, Стр, Кол="") Экспорт Если Кол<>"" Тогда Попытка Возврат Т.ПолучитьЗначение(Стр,Кол); Исключение Сообщить("Не могу получить значение в строк "+Строка(Стр)+" колонке "+Строка(Кол)); КонецПопытки; КонецЕсли; Возврат 0; КонецФункции Процедура ТЗВнести(Т, Кол1="", Зн1=0, Кол2="", Зн2=0, Кол3="", Зн3=0, Кол4="", Зн4=0, Кол5="", Зн5=0 , Кол6="", Зн6=0, Кол7="", Зн7=0, Кол8="", Зн8=0, Кол9="", Зн9=0, Кол10="", Зн10=0) Экспорт Поз=Т.ТекущаяСтрока(); Т.НоваяСтрока(); Стр=Т.КоличествоСтрок(); ТЗУстановить(Т,Стр,Кол1,Зн1); ТЗУстановить(Т,Стр,Кол2,Зн2); ТЗУстановить(Т,Стр,Кол3,Зн3); ТЗУстановить(Т,Стр,Кол4,Зн4); ТЗУстановить(Т,Стр,Кол5,Зн5); ТЗУстановить(Т,Стр,Кол6,Зн6); ТЗУстановить(Т,Стр,Кол7,Зн7); ТЗУстановить(Т,Стр,Кол8,Зн8); ТЗУстановить(Т,Стр,Кол9,Зн9); ТЗУстановить(Т,Стр,Кол10,Зн10); Т.ТекущаяСтрока(Поз); КонецПроцедуры Процедура ТЗИндексация(Т) Экспорт Перем ПредЗн; КолКол=Т.КоличествоКолонок(); КолСтр=Т.КоличествоСтрок(); Для Кол=1 По КолКол Цикл Колонка=Т.ПолучитьПараметрыКолонки(Кол); Сп=СоздатьОбъект("СписокЗначений"); Т.Выгрузить(Сп,,,Колонка); Состояние("Индексирую колонку "+Колонка); ИКолонка="_"+Колонка; Т.НоваяКолонка(ИКолонка); Для Стр=1 По КолСтр Цикл Зн=Т.ПолучитьЗначение(Стр,Колонка); Сп.УдалитьЗначение(1); //Удаляем первое значение в списке Поз=Сп.НайтиЗначение(Зн); Если Поз=0 Тогда Индекс=0; Иначе Индекс=Поз+Стр; КонецЕсли; Т.УстановитьЗначение(Стр,ИКолонка,Индекс); КонецЦикла; КонецЦикла; КонецПроцедуры Функция ТЗПоискПер(Т, Колонка, флСумма=0, Кол1="", Зн1=0, Кол2="", Зн2=0, Кол3="", Зн3=0, Кол4="", Зн4=0, Кол5="", Зн5=0, Кол6="", Зн6=0, Кол7="", Зн7=0, Кол8="", Зн8=0, Кол9="", Зн9=0, Кол10="", Зн10=0) Экспорт Поз=Т.ТекущаяСтрока(); Сумма=0; Для Стр=1 По Т.КоличествоСтрок() Цикл Если Кол1<>"" Тогда Если ТЗПолучить(Т, Стр, Кол1)<>Зн1 Тогда Продолжить; КонецЕсли; КонецЕсли; Если Кол2<>"" Тогда Если ТЗПолучить(Т, Стр, Кол2)<>Зн2 Тогда Продолжить; КонецЕсли; КонецЕсли; Если Кол3<>"" Тогда Если ТЗПолучить(Т, Стр, Кол3)<>Зн3 Тогда Продолжить; КонецЕсли; КонецЕсли; Если Кол4<>"" Тогда Если ТЗПолучить(Т, Стр, Кол4)<>Зн4 Тогда Продолжить; КонецЕсли; КонецЕсли; Если Кол5<>"" Тогда Если ТЗПолучить(Т, Стр, Кол5)<>Зн5 Тогда Продолжить; КонецЕсли; КонецЕсли; Если флСумма=1 Тогда Тек=ТЗПолучить(Т, Стр, Колонка); Если ПустоеЗначение(Тек)=1 Тогда Тек=0; КонецЕсли; Сумма=Сумма+Тек; Иначе Сумма=ТЗПолучить(Т, Стр, Колонка); Прервать; КонецЕсли; КонецЦикла; Т.ТекущаяСтрока(Поз); Возврат Сумма; КонецФункции Функция ТЗПоиск(Т, Колонка, флСумма=0, Кол1="", Зн1=0, Кол2="", Зн2=0, Кол3="", Зн3=0, Кол4="", Зн4=0, Кол5="", Зн5=0, Кол6="", Зн6=0, Кол7="", Зн7=0, Кол8="", Зн8=0, Кол9="", Зн9=0, Кол10="", Зн10=0) Экспорт Перем Кол[10]; Перем _Кол[10]; Перем Зн[10]; Перем Индекс[10]; Перем флПервая, Предложена, Найдена; Сумма=0; //Определяем количество колонок КолКол=0; Если Кол1<>"" Тогда КолКол=КолКол+1; Кол[КолКол]=Кол1; Зн[КолКол]=Зн1; КонецЕсли; Если Кол2<>"" Тогда КолКол=КолКол+1; Кол[КолКол]=Кол2; Зн[КолКол]=Зн2; КонецЕсли; Если Кол3<>"" Тогда КолКол=КолКол+1; Кол[КолКол]=Кол3; Зн[КолКол]=Зн3; КонецЕсли; Если Кол4<>"" Тогда КолКол=КолКол+1; Кол[КолКол]=Кол4; Зн[КолКол]=Зн4; КонецЕсли; Если Кол5<>"" Тогда КолКол=КолКол+1; Кол[КолКол]=Кол5; Зн[КолКол]=Зн5; КонецЕсли; Если Кол6<>"" Тогда КолКол=КолКол+1; Кол[КолКол]=Кол6; Зн[КолКол]=Зн6; КонецЕсли; Если Кол7<>"" Тогда КолКол=КолКол+1; Кол[КолКол]=Кол7; Зн[КолКол]=Зн7; КонецЕсли; Если Кол8<>"" Тогда КолКол=КолКол+1; Кол[КолКол]=Кол8; Зн[КолКол]=Зн8; КонецЕсли; Если Кол9<>"" Тогда КолКол=КолКол+1; Кол[КолКол]=Кол9; Зн[КолКол]=Зн9; КонецЕсли; Если Кол10<>"" Тогда КолКол=КолКол+1; Кол[КолКол]=Кол10; Зн[КолКол]=Зн10; КонецЕсли; Если КолКол=0 Тогда Попытка Возврат Т.Итог(Колонка); Исключение Возврат 0; КонецПопытки; КонецЕсли; флПервая=1; //В первый раз ищем стандартным поиском в каждой колонке Найдена=1; //Позиция найденной строки Для Инд=1 По КолКол Цикл Индекс[Инд]=0; _Кол[Инд]="_"+Кол[Инд]; КонецЦикла; //Ищем первую строку Пока 1=1 Цикл ~Опять: Для Инд=1 По КолКол Цикл Пока Индекс[Инд]<Найдена Цикл //Продолжаем, пока не достигли текущей строки Найдена Если Индекс[Инд]=0 Тогда //Первый поиск Предложена=0; Попытка Если Т.НайтиЗначение(Зн[Инд],Предложена,Кол[Инд])=0 Тогда Возврат Сумма; КонецЕсли; Исключение Возврат 0; КонецПопытки; Иначе //Поиск не средствами 1С, а по индексу Предложена=Число(Т.ПолучитьЗначение(Индекс[Инд],_Кол[Инд])); КонецЕсли; //Здесь в Предложена имеем позицию следующего такого же значения Если Предложена=0 Тогда //Если хоть одного параметра нет, возвращаем 0 Возврат Сумма; КонецЕсли; Индекс[Инд]=Предложена; КонецЦикла; //Если следующая позиция больше текущей строки, переходим на следующую строку Если Индекс[Инд]>Найдена Тогда Найдена=Предложена; Перейти ~Опять; //Доходим во всех колонках до найденной строки КонецЕсли; КонецЦикла; ЗнТек=Т.ПолучитьЗначение(Найдена, Колонка); Если флСумма=0 Тогда Возврат ЗнТек; КонецЕсли; Сумма=Сумма+Число(ЗнТек); Найдена=Найдена+1; КонецЦикла; КонецФункции =================================================================