Как проверить проводки в незаписанном документе «ОперацияБух» на управляемой форме?

Программист 1С v8.3 (Управляемые формы) 1C:Бухгалтерия IT и автоматизация бизнеса
← На главную

В процессе разработки и кастомизации конфигураций на платформе «1С:Предприятие 8» программисты часто сталкиваются с необходимостью валидации данных перед записью объекта. Особое место в этом процессе занимают операции, вводимые вручную — документы типа ДокументОбъект.ОперацияБух. Специфика этого документа заключается в том, что он не имеет собственных табличных частей для хранения проводок. Все движения записываются напрямую в регистр бухгалтерии.

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

Архитектурная специфика документа «ОперацияБух»

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

Когда пользователь добавляет строки в таблицу на форме, они еще не существуют в базе данных (СУБД). Данные находятся исключительно в оперативной памяти клиентского приложения в виде специального объекта платформы — ДанныеФормыКоллекция. Именно поэтому стандартные запросы к базе данных или создание нового набора записей через РегистрыБухгалтерии.Хозрасчетный.СоздатьНаборЗаписей() в этот момент абсолютно бесполезны: они вернут пустой результат.

Анализ опасного решения: почему нельзя использовать ТекущиеДанные

В процессе обсуждения подобных задач на форумах разработчики нередко приходят к решению использовать свойство табличного поля формы напрямую. Например, обращаются к Элементы.Хозрасчетный.ТекущиеДанные на клиенте.

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

  1. Пользователь ввел в операцию пять различных проводок с разными счетами дебета.
  2. Искомый счет (например, 01.01) выбран во второй строке.
  3. При этом курсор (выделение) в момент проверки или нажатия кнопки находится на пятой строке, где выбран счет 10.01.
  4. Если ваша программа использует для проверки ТекущиеДанные, она проверит только пятую строку, вернет значение «Ложь» и пропустит документ, несмотря на то, что во второй строке нужный счет присутствует.

Использовать Элементы.Хозрасчетный.ТекущиеДанные допускается исключительно в интерактивных событиях при изменении конкретной строки (например, в обработчике события ПриИзменении реквизита строки таблицы), но категорически запрещено применять для проверки документа в целом.

Решение 1. Полный обход проводок на клиенте (без вызова сервера)

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

Рассмотрим пример реализации клиентской функции:


&НаКлиенте
Функция ПроверитьНаличиеСчетаВДебетеНаКлиенте(ИскомыйСчет)
    
    // ИскомыйСчет — ссылка на элемент плана счетов "Хозрасчетный"
    Если НЕ ЗначениеЗаполнено(ИскомыйСчет) Тогда
        Возврат Ложь;
    КонецЕсли;
    
    // Обходим коллекцию незаписанных движений на форме
    Для Каждого СтрокаПроводки Из Объект.Движения.Хозрасчетный Цикл
        
        // Сравнение ссылок на клиенте выполняется мгновенно
        Если СтрокаПроводки.СчетДт = ИскомыйСчет Тогда
            Возврат Истина; // Счет найден
        КонецЕсли;
        
    КонецЦикла;
    
    Возврат Ложь; // Счет не найден во всей коллекции
    
КонецФункции

Этот способ является наиболее производительным для простых проверок «по ссылке», так как он не требует контекстного вызова сервера и не нагружает сеть передачей данных формы.

Решение 2. Комплексная проверка на сервере с выгрузкой в Таблицу Значений

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

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


&НаСервере
Функция ПроверитьСчетНаСервере(ИмяСчетаСтрокой)
    
    // Получаем ссылку на счет из плана счетов
    НайденныйСчет = ПланыСчетов.Хозрасчетный.НайтиПоКоду(ИмяСчетаСтрокой);
    
    Если НайденныйСчет.Пустая() Тогда
        Возврат Ложь;
    КонецЕсли;
    
    // Шаг 1. Выгружаем данные формы (коллекцию движений) в реальную таблицу значений
    ТаблицаПроводок = Объект.Движения.Хозрасчетный.Выгрузить();
    
    // Шаг 2. Используем быстрый поиск строк по структуре отбора
    ПараметрыОтбора = Новый Структура;
    ПараметрыОтбора.Вставить("СчетДт", НайденныйСчет);
    
    НайденныеСтроки = ТаблицаПроводок.НайтиСтроки(ПараметрыОтбора);
    
    // Шаг 3. Анализируем результат
    Если НайденныеСтроки.Количество() > 0 Тогда
        // Здесь мы также можем обойти найденные строки для дополнительного анализа субконто
        Возврат Истина;
    КонецЕсли;
    
    Возврат Ложь;
    
КонецФункции

Важные подводные камни при работе с «ОперацияБух»

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

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

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

← На главную