Top.Mail.Ru
Заказать консультацию
специалиста 1С
Отправить заявку

Нажимая на кнопку, вы даете согласие на обработку своих персональных данных и соглашаетесь с политикой конфиденциальности.

Настройки отчетов 1С:Предприятия 7.7

Беседин Василий Посмотреть все статьи >> Ведущий специалист по внедрению 1С франчайзинговой сети "ИнфоСофт".
02.03.2023
517
Время прочтения - 5 мин.
Заказать консультацию

Иногда мы сталкиваемся с разного рода нестандартными задачами. И как-то раз мне досталась такая. Ее суть заключалась в следующем: взять некие фильтры и собрать по ним информацию. Но возник один нюанс. Эти фильтры хранятся в настройках определенного отчета, на самом деле нескольких, в базе 1С:Предприятия 7.7. В этих настройках:

1.png

Казалось бы, в чем сложность? Можно создать структуру справочников под эти настройки, сохранить нужную информацию в них. Но пользователи  периодически меняют их, и нужно всегда использовать их последнюю версию. А у кнопки «Сохранить настройки» обработчика не наблюдается.

В результате изысканий было выяснено, что настройки хранятся в специальных файликах с расширением *.lst (в случае, если в настройках пользователя каталоги пользователей не указаны, они будут лежать в корне папки с базой, иначе – в каталогах пользователя). Найти способ вычислять их названия мне не удалось. Однако название файла остается таким же даже после его удаления, и, соответственно, нужный из них можно вычислить по времени сохранения, добавив туда новую настройку. Все настройки одного отчета хранятся в одном таком файле. Файл этот имеет такой вид:

2.png

Как видим, текст файла состоит из служебного слова «RH1» и строки, очень похожей на список списков значений, переведенный в строку функцией ЗначениеВСтрокуВнутр(), а так же на Json.

Также отмечу, что символ «@» с именем настройки указывает на настройку, открываемую по умолчанию (в данном случае "@КрайнеВажнаяНастройка"). Сами значения настроек хранятся в элементах списков значений под именем поля в виде преобразованном функцией «ЗначениеВСтрокуВнутр()»: Например, из этого отчета нужны период и список основных средств. Значения, определяющие их, будут:

  • Период: {"Дата1","20230101"},{"Дата2","20230331"}

  • Список ОС: {"ВыбСубконто1",{{{"B","0","0","285","0","0","        35
       "},""},{{"B","0","0","285","0","0","        32   "},""},{{"B","0","0","285","0","0","        49
       "},""},{{"B","0","0","285","0","0","        11   "},""}}}

Правда, с той оговоркой, что преобразованными являются только сами значения, а не список. Сама структура файла такова:

3.png

Для удобства работы с параметрами был создан инструментарий из нескольких глобальных функций:

4.png

5.png
< текст для копирования:>

// функции для получения настроек формы отчета, сохраненных для пользователя
//служебная рекурсивная процедура
Функция глПолучитьТокенНастроекОтчета(Стр,УровеньРекурсии = 1)
                        НачалоТокена = 0;
                        КонецИмениТокена = 0;
                        НачалоИмениТокена = 0;
                        НачалоЗначенияТокена = 0;
                        НачалоСтрокиТокена = 0;
                        ИмяТокена = "";
                        ЗначениеТокена = "";
                                                Результат = СоздатьОбъект("СписокЗначений");
                        УровеньВложенности = 0;
                        ДлинаСтроки = СтрДлина(Стр);
                        Для Й = 1 По ДлинаСтроки Цикл
                                                                                              Если (Сред(Стр,Й,1) = "{")И(НачалоТокена = 0) Тогда //начало элемента
                                                                       НачалоТокена = Й;
                                                                       УровеньВложенности = УровеньВложенности + 1;
                                               ИначеЕсли (Сред(Стр,Й,1) = "{")И(НачалоТокена > 0)И( НачалоИмениТокена = 0) Тогда //а нет имени, безымянный список. Значит предыдущую скобку заигнорим
                                                                       НачалоТокена = Й;
                                                                       //УровеньВложенности = УровеньВложенности + 1;
                                               ИначеЕсли (Сред(Стр,Й,1) = """")И(НачалоТокена > 0 )И(НачалоИмениТокена = 0) И(КонецИмениТокена = 0)Тогда //первая кавычка
                                                                       НачалоИмениТокена = Й;
                                               ИначеЕсли (Сред(Стр,Й,1) = """")И(НачалоТокена > 0 ) И(НачалоИмениТокена > 0) И(КонецИмениТокена = 0) Тогда //вторая кавычка
                                                                       КонецИмениТокена = Й;
                                                                       ИмяТокена = Сред(Стр,НачалоИмениТокена+1, КонецИмениТокена - НачалоИмениТокена-1);
                                               ИначеЕсли (Сред(Стр,Й,1) = ",") И(НачалоТокена > 0 ) И(КонецИмениТокена > 0) И(НачалоЗначенияТокена = 0) Тогда //значение
                                                                       НачалоЗначенияТокена = Й;
                                               ИначеЕсли (Сред(Стр,Й,1) = """")И(НачалоТокена > 0 ) И(КонецИмениТокена > 0)И(НачалоЗначенияТокена > 0) И(НачалоСтрокиТокена = 0) И (УровеньВложенности = 1) Тогда //Значение токена у нас конечное
                                                                       НачалоСтрокиТокена = Й;
                                               ИначеЕсли (Сред(Стр,Й,1) = """")И(НачалоТокена > 0 ) И(КонецИмениТокена > 0)И(НачалоЗначенияТокена > 0) И(НачалоСтрокиТокена > 0)И (УровеньВложенности = 1)Тогда //Значение токена у нас конечное и это его конец
                                                                       КонецСтрокиТокена = Й;
                                                                       ЗначениеТокена = Сред(Стр,НачалоСтрокиТокена+1,КонецСтрокиТокена - НачалоСтрокиТокена - 1);
                                               ИначеЕсли (Сред(Стр,Й,1) = "{") И(КонецИмениТокена > 0)И(НачалоЗначенияТокена > 0) И(НачалоСтрокиТокена = 0) Тогда //вложенный список
                                                                       НачалоСтрокиТокена = Й;
                                                                       УровеньВложенности = УровеньВложенности + 1;
                                               ИначеЕсли (Сред(Стр,Й,1) = "{") И(КонецИмениТокена > 0)И(НачалоЗначенияТокена > 0) И(НачалоСтрокиТокена > 0) Тогда //еще более вложенный список
                                                                       УровеньВложенности = УровеньВложенности + 1;
                                               ИначеЕсли (Сред(Стр,Й,1) = "}")И(НачалоТокена > 0)И (УровеньВложенности > 1) Тогда //Конец элемента
                                                                       УровеньВложенности = УровеньВложенности - 1;
                                                                       Если (УровеньВложенности = 1) И (Сред(Стр,Й+1,1) = "}") Тогда //далее идет закрытие, а не следующийэлемент
                                                                                               КонецСтрокиТокена = Й;
                                                                                               СтрокаТокена = Сред(Стр,НачалоСтрокиТокена,КонецСТрокиТокена- НачалоСтрокиТокена+1);
                                                                                               ЗначениеТокена = глПолучитьТокенНастроекОтчета(СтрокаТокена,УровеньРекурсии +1);
                                                                       КонецЕсли;
                                                                                                                      ИначеЕсли (Сред(Стр,Й,1) = "}")И(НачалоТокена > 0) Тогда //Конец элемента
                                                                       Если ИмяТокена = "B" Тогда
                                                                                               ЗначениеТокена = ЗначениеИзСтрокиВнутр(Сред(Стр,НачалоТокена,Й - НачалоТокена+1));
                                                                                               Результат.ДобавитьЗначение(ЗначениеТокена);
                                                                       ИначеЕсли ПустаяСтрока(ИмяТокена) = 0 Тогда
                                                                                               Результат.ДобавитьЗначение(ЗначениеТокена,ИмяТокена);
                                                                       КонецЕсли;
                                                                       УровеньВложенности = УровеньВложенности - 1;
                                                                       НачалоТокена = 0;
                                                                       КонецИмениТокена = 0;
                                                                       НачалоИмениТокена = 0;
                                                                       НачалоЗначенияТокена = 0;
                                                                       НачалоСтрокиТокена = 0;
                                                                       ИмяТокена = "";
                                                                       ЗначениеТокена = "";
                                               КонецЕсли;
                        КонецЦикла;
                        Возврат Результат;
КонецФункции
//функция предполагает, что настройки хранятся в каталоге базы данных
Функция глПолучитьНастройкуОтчетаПоИмени(ИмяФайлаНастроек,ИмяНастройки) Экспорт
                        Текст = СоздатьОбъект("Текст");
                        //Текст.Открыть(КаталогБазыДанных()+"\"+"rh8248.lst");
                        Текст.Открыть(КаталогБазыДанных()+"\"+ИмяФайлаНастроек);
                        СтрокаДанных = "";
                        Для Ы = 1 по Текст.КоличествоСтрок() Цикл
                                               СтрокаДанных = СтрокаДанных+Текст.ПолучитьСтроку(Ы);
                        КОнецЦикла;
                        СтрокаДанных = Сред(СтрокаДанных,6);
                        ЗначениеИзСтрокиДанных = глПолучитьТокенНастроекОтчета(СтрокаДанных);
                        Текст = "";
                        СтрокаДанных = "";
                        Возврат ЗначениеИзСтрокиДанных.получитьЗначение(1).Получить(ИмяНастройки);                         
КонецФункции
  Функция глРазбитьСтрокуНаТокеныИПолучитьТокенПоНомеру(Исх,Делитель,НомерТокена) Экспорт
                        РазбитаяСтрока = СтрЗаменить(Исх,Делитель,РазделительСтрок);
                        Если НомерТокена <= СтрКоличествоСтрок(РазбитаяСтрока) Тогда
                                               Возврат СтрПолучитьСтроку(РазбитаяСтрока,НомерТокена);
                        Иначе
                                               Возврат "";
                        КонецЕсли;
КонецФункции          
  //функция для интерпретации значения не строкового типа и не списка значений.
Функция глПривестиЗначениеНастройкиКТипу(ИмяТипа,ЗначениеНастройки) Экспорт
                        Результат = ЗначениеНастройки;
                        Если Найти(ИмяТипа,"Справочник") <> 0 Тогда
                                               ЗначениеТипа = СоздатьОбъект(ИмяТипа);
                                               ПредставлениеПустогоЗначения= ЗначениеВСтрокуВнутр(ЗначениеТипа);
                                               ПоследнийТокен = глРазбитьСтрокуНаТокеныИПолучитьТокенПоНомеру(ПредставлениеПустогоЗначения,",",7);
                                               Если ПустаяСтрока(ПоследнийТокен) = 0 Тогда
                                                                       ПредставленноеЗначение = СтрЗаменить(ПредставлениеПустогоЗначения,ПоследнийТокен,""""+ЗначениеНастройки+"""}");
                                                                       Результат = ЗначениеИзСтрокиВнутр(ПредставленноеЗначение);
                                               КонецЕсли;
                        ИначеЕсли Найти(ИмяТипа,"Перечисление") <> 0 Тогда
                                               ИмяПеречисления = СтрЗаменить(ИмяТипа,"Перечисление.","");
                                               ПустоеЗначениеПеречисления = Перечисление.ПолучитьАтрибут(ИмяПеречисления).ЗначениеПоНомеру(1);
                                               ПредставлениеПустогоЗначения= ЗначениеВСтрокуВнутр(ПустоеЗначениеПеречисления);
                                               ПоследнийТокен = глРазбитьСтрокуНаТокеныИПолучитьТокенПоНомеру(ПредставлениеПустогоЗначения,",",7);
                                               Если ПустаяСтрока(ПоследнийТокен) = 0 Тогда
                                                                       ПредставленноеЗначение = СтрЗаменить(ПредставлениеПустогоЗначения,ПоследнийТокен,""""+ЗначениеНастройки+"""}");
                                                                       Результат = ЗначениеИзСтрокиВнутр(ПредставленноеЗначение);
                                               КонецЕсли;
                        ИначеЕсли Найти(ИмяТипа,"Строка") <> 0 Тогда
                                               Результат = ЗначениеИзСтрокиВнутр("{""S"",""0"",""0"",""0"",""0"",""0"","""+ЗначениеНастройки +"""}");
                        ИначеЕсли Найти(ИмяТипа,"Дата") <> 0 Тогда
                                               Результат = ЗначениеИзСтрокиВнутр("{""D"",""0"",""0"",""0"",""0"",""0"","""+ЗначениеНастройки +"""}");           
                        ИначеЕсли Найти(ИмяТипа,"Число") <> 0 Тогда
                                               Результат = ЗначениеИзСтрокиВнутр("{""N"",""0"",""0"",""0"",""0"",""0"","""+ЗначениеНастройки +"""}");
                        КонецЕсли;
                        Возврат Результат;
КонецФункции

< /текст для копирования>

Подпишитесь на дайджест!
Подпишитесь на дайджест, и получайте ежемесячно подборку полезных статей.

Нажимая на кнопку, вы даете согласие на обработку своих персональных данных и соглашаетесь с политикой конфиденциальности.

В результате после написания кода в обработке:

6.png

Получим результат:

7.png

 

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


Заказать консультацию специалиста 1С
Оставьте заявку и наши эксперты проконсультируют вас по данной статье.
Отправить заявку

Нажимая на кнопку, вы даете согласие на обработку своих персональных данных и соглашаетесь с политикой конфиденциальности.

Рассказать друзьям
Для разработчиков 1С
Вам может быть интересно: