Как исправить ошибку «Не выбран документ!» при программном добавлении строки в 1С 7.7?

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

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

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

В чем первопричина ошибки: «Объект» против «Ссылки»

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

Давайте выясним разницу между этими состояниями:

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

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

Проанализируем некорректный код автора темы:


дВып = СоздатьОбъект("Документ.БанковскаяВыписка");
дВып.Новый(); 
// ... заполнение шапки ...
дВып.Записать();  

текВып = докВып.ТекущийДокумент(); // Здесь переменная текВып становится ССЫЛКОЙ
// ...
текВып.НоваяСтрока(); // ОШИБКА! Попытка модификации ссылки

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

---

Решение №1: Правильный алгоритм создания нового документа

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

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


// Шаг 1: Создаем объект модификации конкретного вида документа
дВып = СоздатьОбъект("Документ.БанковскаяВыписка");

// Шаг 2: Инициализируем новый документ в оперативной памяти
дВып.Новый(); 

// Шаг 3: Заполняем реквизиты шапки документа
дВып.РСчет = НДС.ТекущийЭлемент();
дВып.СчетУчета = НДС.СчетУчета;
Если дВып.СчетУчета.Выбран() = 0 Тогда
    дВып.СчетУчета = СчетПоКоду(?(дВып.РСчет.Валюта = Гривня, "31.1", "31.2"));
КонецЕсли;
дВып.СчетНДС = дВып.РСчет.СпецСчетНДС; 
дВып.Фирма = НДС.Фирма;         
дВып.ДатаДок = ДатаДвижения; 

// Шаг 4: Программно добавляем строки в табличную часть ДО записи документа
// Цикл для демонстрации добавления нескольких строк
Для НомерСтроки = 1 По 3 Цикл
    дВып.НоваяСтрока(); // Метод вызывается у ОБЪЕКТА, созданного через СоздатьОбъект!
    
    // Заполняем реквизиты внутри созданной строки
    дВып.Субконто1 = ЗначениеСубконто;
    дВып.Сумма = 100 * НомерСтроки;
КонецЦикла;

// Шаг 5: Выполняем однократную запись всего документа целиком в базу данных
дВып.Записать();  

При таком подходе исключаются лишние обращения к СУБД, а весь документ (вместе с шапкой и табличной частью) записывается за одну транзакцию. Это гарантирует целостность данных и полностью предотвращает появление пустых "документов-призраков" без табличной части.

---

Решение №2: Правильное изменение уже существующего документа

Что делать, если документ уже существует в базе данных (был создан ранее), и вам необходимо программно открыть его и добавить новые строки? Для этого нельзя использовать ссылку напрямую. Нам потребуется создать новый объект, спозиционировать его на нужной ссылке, внести изменения и сохранить их.

Давайте разберем этот процесс по шагам:


// Предположим, у нас есть ссылка на документ в переменной СсылкаНаДок
СсылкаНаДок = ВыбранныйРанееДокумент.ТекущийДокумент();

// Шаг 1: Создаем пустой объект для работы с документами нужного вида
ДокМодификации = СоздатьОбъект("Документ.БанковскаяВыписка");

// Шаг 2: Позиционируем объект на существующем документе по его ссылке
Если ДокМодификации.НайтиДокумент(СсылкаНаДок) = 1 Тогда
    
    // Шаг 3: Объект успешно найден и выбран. Теперь мы можем его изменять!
    ДокМодификации.НоваяСтрока();
    
    // Заполняем новые реквизиты табличной части
    ДокМодификации.Сумма = 500;
    
    // Шаг 4: Обязательно записываем внесенные изменения
    ДокМодификации.Записать();
    
    Сообщить("Строка успешно добавлена в существующий документ!");
Иначе
    Предупреждение("Не удалось найти указанный документ в базе данных!");
КонецЕсли;

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

---

Дополнительные причины возникновения ошибки «Не выбран документ!»

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

Резюмируем: Для исключения ошибки Не выбран документ! всегда четко разделяйте сущности. Заполнение данных и вызовы метода НоваяСтрока() делайте только для объектов, полученных через СоздатьОбъект(), и избегайте необоснованного использования метода ТекущийДокумент() в цепочках модификации данных.

← На главную