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

Программист 1С v7.7 Бухгалтерский учет IT и автоматизация бизнеса
← На главную

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

Проблема неактивной кнопки выбора реквизита на форме

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

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

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

Решение проблемы с помощью метода НазначитьТип()

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

Разберем подробнее синтаксис этого метода:

НазначитьТип(<ИмяРеквизита>, <ИмяТипа>, <Длина>, <Точность>)

Посмотрим на пример. Предположим, у нас на форме есть реквизит Контрагент и связанный с ним реквизит Основание (тип «Неопределенный»), который должен принимать значение договора. Мы хотим, чтобы при выборе контрагента тип реквизита Основание жестко ограничивался справочником договоров.

Разберем по шагам код, который решает эту задачу:


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

После вызова метода НазначитьТип("Основание", "Справочник.Договоры") платформа мгновенно активирует кнопку выбора на форме, и при ее нажатии откроется форма выбора справочника «Договоры».

Важный подводный камень: Если вы записываете строковые значения в реквизит типа «Неопределенный» без предварительного вызова метода НазначитьТип(), 1С 7.7 может урезать строку во внутреннем представлении до стандартной длины (около 23 символов). Чтобы избежать потери данных, всегда предварительно назначайте тип с указанием длины строки:


НазначитьТип("Основание", "Строка", 100);
Основание = "Произвольный длинный текст описания сделки";

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

Перейдем ко второй распространенной проблеме. Разработчики часто совершают классическую ошибку в процедуре модуля документа ОбработкаПроведения(), пытаяс напрямую обратиться к реквизитам табличной части. Рассмотрим типичный ошибочный код:


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

При выполнении этого кода в режиме отладки мы увидим, что переменная ОсновнойДолг (которая является реквизитом табличной части) возвращает значение 0, хотя в самом документе табличная часть заполнена суммами.

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

Построчное проведение документа (цикл по табличной части)

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

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

Модифицируем процедуру проведения, добавив в нее цикл по строкам:


Процедура ОбработкаПроведения()
    // Инициализируем выборку строк табличной части
    ВыбратьСтроки();
    
    // Запускаем цикл по всем строкам документа
    Пока ПолучитьСтроку() = 1 Цикл
        // Теперь внутри цикла реквизит "ОсновнойДолг" 
        // содержит значение текущей активной строки!
        Операция.НоваяПроводка(); 
        Операция.АвторПроводки = Пользователь;
        Операция.Дебет.Счет = Счет;
        Операция.Дебет.Контрагенты = Контрагент2;
        Операция.Дебет.Основание = Основание2;
        
        Операция.Кредит.Счет = Счет;
        Операция.Кредит.Контрагенты = Контрагент1;
        Операция.Кредит.Основание = Основание1;
        
        Операция.Сумма = ОсновнойДолг; // Сумма из текущей строки ТЧ
        Операция.СодержаниеПроводки = "Основной долг по " + Основание2;
        Операция.НомерЖурнала = "ТВ";
    КонецЦикла;
    
    // Записываем сформированную операцию
    Операция.Записать();
КонецПроцедуры

Проведение по суммарному итогу табличной части

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


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

Связывание проводок со строками: метод ПривязыватьСтроку()

При построчном формировании движений в 1С 7.7 хорошей практикой является использование системного метода ПривязыватьСтроку(). Он связывает создаваемую проводку с номером текущей строки табличной части документа:

Операция.ПривязыватьСтроку(НомерСтроки);

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

Тонкости заполнения содержания в бухгалтерской операции

Часто начинающие программисты сталкиваются с тем, что в журнале проводок содержание созданных документов остается пустым, хотя в коде проведения была заполнена строка содержания. Разберем разницу между двумя ключевыми свойствами объекта Операция:

  1. Операция.Содержание — это текстовое описание всей хозяйственной операции. Это свойство характеризует весь документ в целом и отображается в общем журнале операций (например, "Взаимозачет", "Поступление товаров").
  2. Операция.СодержаниеПроводки — это комментарий, относящийся к конкретной проводке внутри операции (к дебету и кредиту). Каждая проводка внутри одной операции может иметь свое уникальное содержание (например, "Оплата за комплектующие", "НДС по ставке 20%").

Если в коде вы напишете Операция.Содержание = "Текст" внутри цикла создания проводок, вы будете перезаписывать общее содержание документа, а содержание у самих бухгалтерских проводок останется пустым. Правильный подход — заполнять именно СодержаниеПроводки для каждой новой сформированной записи:


// Правильное заполнение содержания для конкретной проводки
Операция.НоваяПроводка();
Операция.СодержаниеПроводки = "Оплата по договору: " + СокрЛП(Договор);

Резюме

Мы подробно рассмотрели особенности разработки документов в среде 1С:Предприятие 7.7. Для активации кнопок выбора у полей с неопределенным типом всегда используйте метод НазначитьТип(). При проведении документов не забывайте обходить табличную часть с помощью цикла ВыбратьСтроки() / ПолучитьСтроку() или использовать метод Итог() для получения суммарных данных. Различайте общее содержание операции и содержание конкретных проводок, чтобы сделать бухгалтерский учет прозрачным и удобным для конечных пользователей.

← На главную