Как переделать код обработки настроек из формы справочника под форму обработки в 1С?

Программист 1С v8.3 (Управляемые формы)
← На главную

При разработке функционала в 1С часто возникает необходимость перенести логику из одного типа объекта в другой. В нашем случае, мы рассмотрим ситуацию, когда необходимо адаптировать код, предназначенный для формы справочника, под форму обработки, при этом исключив прямую зависимость от ссылки на элемент справочника. Такая задача может возникнуть, если первоначальная разработка была реализована в справочнике, а теперь требуется сделать ее локально, в обработке, без создания или использования элементов справочника.

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


Если НЕ ЗначениеЗаполнено(Объект.Ссылка) Тогда Возврат; КонецЕсли;
ДанныеНастроек = Справочники.Настройки.ПолучитьНастройки(Объект.Ссылка);
Если ДанныеНастроек = НЕОПРЕДЕЛЕНО Тогда Возврат; КонецЕсли;
Объект.подкл_Версия = ПолучитьЗначениеНастройки(ДанныеНастроек, "подкл_Версия");
Объект.подкл_ИмяСервера = ПолучитьЗначениеНастройки(ДанныеНастроек, "ИмяСервера");
СериализованнаяНастройка = ПолучитьЗначениеНастройки(ДанныеНастроек, "Отбор");

Основная проблема здесь заключается в использовании Объект.Ссылка и функции Справочники.Настройки.ПолучитьНастройки(), которые напрямую завязаны на существовании элемента справочника "Настройки". В форме обработки такого объекта не будет, и нам нужно найти альтернативные способы получения и хранения этих настроек.

Подход 1: Использование структуры для имитации объекта справочника

Самый прямой и часто используемый способ, предложенный в обсуждении, – это заменить ссылку на объект справочника на структуру. Вместо того, чтобы получать настройки из существующего справочника, мы можем создать новую структуру и вручную заполнить ее необходимыми полями. Эта структура будет выступать в роли "заглушки" или временного хранилища данных, которые ранее получались из справочника.

Рассмотрим по шагам, как это можно реализовать:

  1. Создание структуры: Вместо использования Объект.Ссылка, мы создадим новый объект Структура.
  2. Заполнение полей структуры: Мы добавим в эту структуру все поля, которые ожидаются функцией ПолучитьНастройки или которые используются далее в коде. Важно знать, какие именно поля требуются функции ПолучитьНастройки. Если эта функция является вашей собственной и ожидает ссылку на справочник, возможно, ее придется адаптировать для приема структуры или другого типа данных. Однако, судя по коду, ПолучитьЗначениеНастройки уже принимает структуру ДанныеНастроек, что упрощает задачу.
  3. Использование структуры: После заполнения, эта структура может быть использована в качестве аргумента для вашей функции ПолучитьЗначениеНастройки или для непосредственного присвоения значений реквизитам обработки.

Вот пример реализации с использованием структуры:


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

// Создаем новую структуру для хранения 'настроек'
ДанныеНастроек = Новый Структура;

// Заполняем поля структуры, имитируя данные, которые ранее получались из справочника
// Здесь мы вручную определяем значения для нужных 'настроек'
// Если 'ПолучитьНастройки' был бы нашей функцией, ее пришлось бы переделать
// для приема структуры, но если она уже не вызывается, то это не нужно.
// Предполагаем, что ПолучитьЗначениеНастройки работает со структурой.

// Пример заполнения полей, если бы они были простыми значениями:
ДанныеНастроек.Вставить("подкл_Версия", "0.1"); // Пример значения версии
ДанныеНастроек.Вставить("ИмяСервера", "МойСерверПродакшн"); // Пример имени сервера

// Для более сложных полей, таких как "Отбор", если это тоже должна быть структура или массив
ДанныеНастроек.Вставить("Отбор", Новый Структура);
ДанныеНастроек.Отбор.Вставить("ИмяОтбора1", "ЗначениеОтбора1");
ДанныеНастроек.Отбор.Вставить("ИмяОтбора2", "ЗначениеОтбора2");
// и так далее для всех необходимых полей.

// Если ДанныеНастроек = НЕОПРЕДЕЛЕНО Тогда Возврат; КонецЕсли; // Этот шаг становится ненужным, т.к. мы сами создали структуру

// Теперь используем созданную структуру для получения значений, как и ранее
// Вместо Объект.подкл_Версия, присваиваем значение реквизитам формы обработки
// или временным переменным.
// Предположим, что в обработке есть реквизиты с такими же именами.
ВашРеквизитВерсия = ПолучитьЗначениеНастройки(ДанныеНастроек, "подкл_Версия");
ВашРеквизитИмяСервера = ПолучитьЗначениеНастройки(ДанныеНастроек, "ИмяСервера");
СериализованнаяНастройка = ПолучитьЗначениеНастройки(ДанныеНастроек, "Отбор");

// Если ПолучитьЗначениеНастройки - ваша функция, то ее код может выглядеть так:
// Функция ПолучитьЗначениеНастройки(ИсточникДанных, ИмяНастройки)
//     Если ИсточникДанных.Свойство(ИмяНастройки) Тогда
//         Возврат ИсточникДанных[ИмяНастройки];
//     Иначе
//         Возврат Неопределено;
//     КонецЕсли;
// КонецФункции

Этот подход позволяет полностью уйти от зависимости от справочника. Важно помнить, что если функция Справочники.Настройки.ПолучитьНастройки() была сложной и выполняла дополнительную логику (например, читала данные из базы), то эту логику придется воспроизвести непосредственно в обработке или в новой функции, которая будет работать со структурой или другими источниками данных.

Подход 2: Хранение настроек в реквизитах самой обработки

Для более простого хранения настроек, которые не требуют сложной логики извлечения, вы можете добавить реквизиты непосредственно в форму обработки. Эти реквизиты будут хранить значения, такие как "подкл_Версия", "ИмяСервера", "Отбор" и другие.

  1. Добавление реквизитов: В конфигураторе, в объекте "Обработка", на вкладке "Реквизиты" или непосредственно в форме обработки, добавьте необходимые реквизиты с соответствующими типами (например, Строка для версии и имени сервера, или Структура/Массив для отбора).
  2. Заполнение реквизитов: При открытии формы обработки (например, в обработчике события ПриСозданииНаСервере) эти реквизиты могут быть заполнены начальными значениями. Эти значения могут быть жестко заданы в коде, получены из констант, или восстановлены из пользовательских настроек (см. следующий пункт).
  3. Использование реквизитов: Затем вы можете обращаться к этим реквизитам напрямую: ЭтаФорма.подкл_Версия, ЭтаФорма.ИмяСервера и так далее.
  4. Сохранение реквизитов (опционально): Если настройки должны сохраняться между сеансами работы пользователя, вы можете использовать механизмы сохранения настроек формы (см. подход 5) или ХранилищеЗначения.

Подход 3: Использование Констант для общих настроек

Если настройки должны быть общими для всей информационной базы, изменяются редко и доступны всем пользователям (или определенным группам), можно использовать константы. Каждая константа хранит одно значение, и к ней можно обращаться из кода.

  1. Создание констант: В конфигураторе создайте новые константы (например, "ОсновнаяВерсияПодключения", "ИмяСервераПодключения") с соответствующими типами.
  2. Заполнение констант: Значения констант можно установить вручную в пользовательском режиме (раздел "Администрирование" или аналогичный).
  3. Использование констант: В коде обработки обращайтесь к ним напрямую: Константы.ОсновнаяВерсияПодключения.Получить(), Константы.ИмяСервераПодключения.Получить().

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

Подход 4: Использование ХранилищаЗначения для сложных настроек

Для хранения сложных типов данных, таких как таблицы значений, структуры, массивы, двоичные данные или даже внешние обработки и отчеты, можно использовать объект ХранилищеЗначения. Этот механизм позволяет сериализовать (преобразовать в двоичные данные) практически любой объект 1С и сохранить его в базе данных, например, в реквизите константы или реквизите формы обработки (если реквизит имеет тип ХранилищеЗначения).

  1. Сохранение данных: Для сохранения данных в ХранилищеЗначения используйте конструктор:
    
    ВашиНастройки = Новый Структура;
    ВашиНастройки.Вставить("Версия", "1.0.1");
    ВашиНастройки.Вставить("СписокПользователей", Новый Массив);
    // ... заполнение других настроек
    
    Хранилище = Новый ХранилищеЗначения(ВашиНастройки);
    // Теперь 'Хранилище' можно записать в константу или реквизит формы
    // Например, если есть константа 'НастройкиОбработки' типа ХранилищеЗначения:
    // Константы.НастройкиОбработки.Установить(Хранилище);
    
  2. Восстановление данных: Для восстановления данных из ХранилищаЗначения используйте метод Получить():
    
    // Предположим, что ХранилищеЗначения было получено из константы
    // Хранилище = Константы.НастройкиОбработки.Получить();
    
    Если Хранилище <> Неопределено Тогда
        ВашиНастройки = Хранилище.Получить();
        // Теперь можно работать с ВашиНастройки как с обычной структурой
        Версия = ВашиНастройки.Версия;
    Иначе
        // Обработка случая, когда настроек нет
        ВашиНастройки = Новый Структура;
    КонецЕсли;
    

ХранилищеЗначения очень гибко и позволяет сохранять данные непосредственно в базе, включая их в резервные копии. При сохранении можно использовать сжатие данных, что может быть полезно для больших объемов.

Подход 5: Механизм "Хранилище настроек" для пользовательских настроек формы

Платформа 1С предлагает встроенный механизм "Хранилище настроек" для сохранения информации о настройках пользователя между сеансами работы. Это особенно удобно для форм обработок, где пользователь может часто менять какие-либо параметры.

Существуют различные виды хранилищ:

Чтобы использовать этот механизм, мы можем сохранить настройки при закрытии формы и загрузить при открытии, используя методы СохранитьЗначение() и ВосстановитьЗначение().

  1. Сохранение настроек: В обработчике события формы ПриЗакрытииНаСервере или по кнопке "Сохранить настройки":
    
    // Объект, который мы хотим сохранить (например, структура с нашими настройками)
    НастройкиДляСохранения = Новый Структура;
    НастройкиДляСохранения.Вставить("подкл_Версия", ЭтотОбъект.подкл_Версия);
    НастройкиДляСохранения.Вставить("ИмяСервера", ЭтотОбъект.ИмяСервера);
    НастройкиДляСохранения.Вставить("ОтборСКД", ЭтаФорма.КомпоновщикНастроек.Настройки.Отбор); // Пример сохранения отбора СКД
    
    // Сохраняем значение в хранилище, указывая ключ и объект.
    // Ключ обычно состоит из имени обработки и уникального идентификатора,
    // чтобы не пересекаться с настройками других форм.
    ХранилищеНастроекКлиента.Сохранить("МояОбработка_ОсновныеНастройки", НастройкиДляСохранения);
    
  2. Восстановление настроек: В обработчике события формы ПриСозданииНаСервере:
    
    НастройкиВосстановленные = ХранилищеНастроекКлиента.Восстановить("МояОбработка_ОсновныеНастройки");
    
    Если НастройкиВосстановленные <> Неопределено Тогда
        ЭтотОбъект.подкл_Версия = НастройкиВосстановленные.подкл_Версия;
        ЭтотОбъект.ИмяСервера = НастройкиВосстановленные.ИмяСервера;
        Если НастройкиВосстановленные.Свойство("ОтборСКД") Тогда
            ЭтаФорма.КомпоновщикНастроек.ЗагрузитьНастройки(НастройкиВосстановленные.ОтборСКД); // Для СКД
        КонецЕсли;
    Иначе
        // Устанавливаем значения по умолчанию, если настроек еще нет
        ЭтотОбъект.подкл_Версия = "1.0";
        ЭтотОбъект.ИмяСервера = "DefaultServer";
    КонецЕсли;
    

Важно помнить, что эти методы работают только при корректном завершении работы программы или явном вызове сохранения. Если программа аварийно завершится, последние несохраненные настройки могут быть потеряны.

Подход 6: Работа с КомпоновщикомНастроек и Отбором (для СКД)

Если строка СериализованнаяНастройка = ПолучитьЗначениеНастройки(ДанныеНастроек, "Отбор"); относится к Системе Компоновки Данных (СКД) и "Отбор" является частью настроек компоновщика, то для работы с ним в обработке мы должны использовать объект КомпоновщикНастроекКомпоновкиДанных.

Рассмотрим, как это работает:

  1. Добавление реквизита КомпоновщикаНастроек: На форму обработки необходимо добавить реквизит типа КомпоновщикНастроекКомпоновкиДанных. Обычно его называют КомпоновщикНастроек.
  2. Инициализация КомпоновщикаНастроек: В обработчике события формы ПриСозданииНаСервере необходимо создать и инициализировать этот компоновщик, загрузив в него схему компоновки данных (которая может быть встроена в обработку или храниться в макетах):
    
    // Инициализация КомпоновщикаНастроек
    ЭтотОбъект.КомпоновщикНастроек = Новый КомпоновщикНастроекКомпоновкиДанных;
    ЭтотОбъект.КомпоновщикНастроек.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных")));
    
    // Если нужно, загрузить ранее сохраненные настройки
    // ЭтоОбъект.КомпоновщикНастроек.ЗагрузитьНастройки(ВосстановленныеНастройки.ОтборСКД);
    
  3. Программная манипуляция Отбором: После инициализации, вы можете программно манипулировать элементами отбора, добавлять новые, устанавливать вид сравнения и значения, как это было показано в одном из полезных сообщений:
    
    // КомпМакета = новый КомпоновщикМакетаКомпоновкиДанных; // Это не нужно для настройки Отбора
    
    // Получаем объект Отбор из настроек компоновщика
    Отбор = ЭтаФорма.КомпоновщикНастроек.Настройки.Отбор;
    
    // Добавляем новый элемент отбора
    ЭлементОтбора = Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
    
    // Устанавливаем левое значение (поле, по которому отбираем)
    ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("ИмяПоляДляОтбора"); // Например, "Контрагент", "Номенклатура.Вид"
    
    // Включаем использование элемента отбора
    ЭлементОтбора.Использование = Истина;
    
    // Устанавливаем вид сравнения
    ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно; // Или Другое, например, ВСписке, Больше, Меньше
    
    // Устанавливаем правое значение (значение, с которым сравниваем)
    ЭлементОтбора.ПравоеЗначение = "ЧтоТоТам"; // Например, Справочники.Контрагенты.НайтиПоКоду("00001");
    
    // Если нужно добавить отбор по нескольким значениям (например, для ВидСравненияКомпоновкиДанных.ВСписке)
    // ЭлементОтбора.ПравоеЗначение = Новый СписокЗначений;
    // ЭлементОтбора.ПравоеЗначение.Добавить("Значение1");
    // ЭлементОтбора.ПравоеЗначение.Добавить("Значение2");
    
    // Если Отбор хранился в ДанныеНастроек как структура,
    // то мы можем его восстановить или дополнить
    // Например, если в структуре 'ДанныеНастроек' есть поле 'Отбор',
    // которое содержит список или структуру с элементами отбора
    // Это требует адаптации вашей функции ПолучитьЗначениеНастройки
    // и логики обработки СериализованнаяНастройка.
    
  4. Вывод отбора на форму: Чтобы пользователь мог интерактивно настраивать фильтрацию данных, вы можете добавить на форму элемент типа "Поле формы" и связать его с реквизитом КомпоновщикНастроек.Настройки.Отбор.
  5. Сохранение/восстановление настроек компоновщика: Настройки компоновщика (включая отбор) можно сохранять в информационной базе с помощью ХранилищаЗначения или механизмов пользовательских настроек (см. подход 5), чтобы пользовательские фильтры сохранялись между сеансами.

Дополнительные рекомендации и уточнения

При переделке кода, помимо основных подходов, мы должны учесть некоторые важные моменты:

  1. Сериализация: Для сохранения значений сложных типов в том виде, который позволяет записывать их и затем восстанавливать, используется сериализация. В 1С есть методы ЗначениеВФайл() и ЗначениеИзФайла() для сохранения/восстановления временных значений в файловой системе, а также ЗначениеВСтрокуВнутр() и ЗначениеИзСтрокиВнутр() для сохранения/восстановления значений в строку. Последние, однако, не рекомендуются для большинства случаев из-за их специфического формата и потенциальных проблем с обратной совместимостью версий платформы. Чаще всего для хранения в базе предпочтительнее ХранилищеЗначения.
  2. Передача параметров при открытии обработки: Если обработка должна работать с конкретными данными, которые ранее выбирались в справочнике, то при открытии формы обработки можно передавать несколько параметров. Для этого удобно использовать объект Структура. Например:
    
    Параметры = Новый Структура("ИмяСервера, Версия", "TestServer", "2.0");
    ОткрытьФорму("Обработка.МояОбработка.Форма", Параметры);
    
    В форме обработки эти параметры можно получить в обработчике ПриСозданииНаСервере через ЭтаФорма.Параметры.
  3. Адаптация функции ПолучитьНастройки(): Если функция Справочники.Настройки.ПолучитьНастройки(Объект.Ссылка) была не просто заглушкой, а выполняла сложную логику получения настроек из базы данных или других источников, то вам придется перенести эту логику. Возможно, потребуется создать новую экспортную функцию в модуле вашей обработки или в общем модуле, которая будет получать настройки уже без привязки к конкретной ссылке справочника. Например, она может принимать некую "идентификационную строку" или структуру, по которой определяются нужные настройки.

Выбор конкретного способа зависит от требований к хранению настроек: нужна ли их персистентность между сеансами работы, доступность для разных пользователей, сложность хранимых данных и необходимость интерактивного изменения. Комбинируя эти подходы, вы сможете эффективно перенести функционал из формы справочника в форму обработки, обеспечив при этом необходимую гибкость и управляемость настройками.

← На главную