1C-CodeОсновы 1С → Справочники и документы: чтение и запись

Справочники и документы: чтение и запись

Здесь кончается «просто язык» и начинается сама 1С: ссылка, объект, запись и проведение.

Глава 11 из 36 · чтение примерно 30 минут

Всё, что было до сих пор, — обычное программирование: переменные, условия, циклы, коллекции. Такое есть в любом языке.

С этой главы начинается то, ради чего 1С существует: работа с данными учёта. Справочники, документы, чтение и запись.

Два главных вида данных

Справочник — список того, что существует само по себе и живёт долго: номенклатура, контрагенты, склады, сотрудники. Элемент справочника не привязан ко времени.

Документ — событие, случившееся в определённый момент: реализация, поступление, оплата. У документа всегда есть дата и номер, и он меняет учётные итоги, когда его проводят.

Разница не формальная. Если сущность отвечает на вопрос «что это» — справочник. Если на вопрос «что произошло и когда» — документ.

Ссылка — не сами данные

Это ключевое понятие 1С.

Когда вы находите элемент справочника, вы получаете не сам элемент, а ссылку на него. Ссылка — это адрес, указатель на запись в базе. Сама по себе она почти ничего не весит.

А вот когда вы пишете Товар.Артикул, платформа идёт по этому адресу в базу и читает реквизит. Каждое обращение через точку — отдельное чтение.

Читайте точку вслух как «сходить в базу»

Приём, который экономит годы: читая Ссылка.Реквизит, проговаривайте про себя «сходить в базу за реквизитом».

Тогда строка СтрокаФайла.Товар.Поставщик.Регион внутри цикла сразу читается как «три похода в базу на каждой строке документа» — и становится видно, почему это медленно.

В запросе точка ведёт себя иначе: там она превращается в соединение, и лишних обращений не создаёт. Но об этом — в главе про запросы.

Найти и прочитать

Товар = Справочники.Номенклатура.НайтиПоНаименованию("Гвозди 100мм");

Если Не ЗначениеЗаполнено(Товар) Тогда
	Возврат "не найден";
КонецЕсли;

Возврат Товар.Артикул;
ЧастьЧто означает
Справочникиобщая точка входа ко всем справочникам конфигурации
.Номенклатураимя конкретного справочника — как он назван в конфигурации
НайтиПоНаименованиювернёт ссылку или ПУСТУЮ ссылку, если не нашлось
ЗначениеЗаполненопроверка перед использованием — обязательна
Товар.Артикулвот здесь и происходит чтение из базы

Не нашлось — это не ошибка, а пустая ссылка

НайтиПоНаименованию не падает, когда ничего не нашла. Она возвращает пустую ссылку — ссылку, которая никуда не ведёт.

Падение случится строкой ниже, на Товар.Артикул: обращение к реквизиту несуществующего элемента. И в сообщении будет указана эта строка, а не та, где на самом деле проблема.

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

Упражнение 1. Артикул по наименованию

Напишите функцию Артикул(Наименование): найти товар в справочнике Номенклатура и вернуть его артикул. Если товара нет — вернуть пустую строку. Проверка спрашивает несуществующий товар и ждёт пустую строку.

Решается в тренажёре: код запускается и проверяется сразу.

Ссылка и объект — разные вещи

По ссылке можно только читать. Чтобы что-то изменить, нужен объект — он получается вызовом ПолучитьОбъект().

Разница принципиальна и по смыслу, и по цене: ссылка легка, а объект — это вся запись, поднятая из базы в память, вместе со всеми реквизитами и табличными частями.

✓ Ссылка — читать

Товар = Справочники.Номенклатура
	.НайтиПоНаименованию("Гвозди 100мм");

Сообщить(Товар.Артикул);

// Товар.Артикул = "НОВЫЙ";  ← так нельзя

Дёшево. Так работают, когда данные только читают.

✕ Объект — менять

Объект = Товар.ПолучитьОбъект();

Объект.Артикул = "НОВЫЙ";
Объект.Записать();

Дороже: подняли всю запись. Зато можно менять и записывать.

Что чем делают

ЗадачаКак
найти по имениСправочники.Х.НайтиПоНаименованию("…")
найти по кодуСправочники.Х.НайтиПоКоду("…")
найти документДокументы.Х.НайтиПоНомеру("…")
создать новый элементСправочники.Х.СоздатьЭлемент()
создать документДокументы.Х.СоздатьДокумент()
получить изменяемый объектСсылка.ПолучитьОбъект()
сохранить измененияОбъект.Записать()
провести документОбъект.Записать(РежимЗаписиДокумента.Проведение)
проверить, что нашлосьЗначениеЗаполнено(Ссылка)

Создание и запись

Новый элемент создают методом СоздатьЭлемент(). Он сразу возвращает объект — ссылки ещё нет, потому что в базе ничего нет.

Ссылка появится только после Записать(). До этого момента элемент существует лишь в памяти, и если программа прервётся — не останется ничего.

Новый элемент справочника

Объект = Справочники.Номенклатура.СоздатьЭлемент();
Объект.Наименование = "Саморезы 50мм";
Объект.Артикул = "СМ-50";
Объект.Записать();

Возврат Объект.Ссылка;   // ссылка появилась только сейчас
ЧастьЧто означает
СоздатьЭлементсразу объект: создаём то, чего в базе ещё нет
Наименованиеобычное присваивание — объект можно менять
Записать()вот здесь запись реально попадает в базу
Объект.Ссылкадо Записать() ссылки нет — и хранить её негде

Упражнение 2. Завести товар

Напишите ЗавестиТовар(Наименование): создать элемент справочника Номенклатура, заполнить наименование, записать и вернуть наименование записанного элемента через его ссылку.

Решается в тренажёре: код запускается и проверяется сразу.

Табличная часть документа

У документа кроме обычных реквизитов (дата, номер, контрагент) есть табличные части — вложенные таблицы. У реализации это обычно Товары: строка на каждую позицию.

Обходят её как обычную коллекцию, циклом Для Каждого. Каждая строка — набор своих реквизитов: номенклатура, количество, цена, сумма.

Обход строк документа

Ссылка = Документы.РеализацияТоваров.НайтиПоНомеру("000001");
Объект = Ссылка.ПолучитьОбъект();

Результат = 0;
Для Каждого СтрокаФайла Из Объект.Товары Цикл
	Результат = Результат + СтрокаФайла.Сумма;
КонецЦикла;
ЧастьЧто означает
Объект.Товарыимя табличной части — как она названа в конфигурации
Стрстрока табличной части, у неё свои реквизиты
Стр.Суммареквизит строки, а не документа
зачем объектздесь он взят, чтобы менять; только для чтения хватило бы запроса

Упражнение 3. Сумма по строкам документа

Напишите ИтогДокумента(Номер): найти документ РеализацияТоваров по номеру, сложить Сумма по всем строкам табличной части Товары. Если документа нет — вернуть 0. Проверка передаёт номер 000001.

Решается в тренажёре: код запускается и проверяется сразу.

Проведение: чем документ отличается от записи

Записать() у документа просто сохраняет его. Учётные итоги при этом не меняются: документ лежит в базе, но остатки и обороты его не видят.

Меняет итоги проведение: Записать(РежимЗаписиДокумента.Проведение). Только тогда документ формирует движения по регистрам — товар списывается со склада, долг появляется у контрагента.

Отсюда классическая жалоба «отчёт не видит документ». Документ есть, он записан — просто не проведён.

Читать много объектов циклом — почти всегда ошибка

У менеджера есть метод Выбрать(), дающий выборку по всем элементам:

Выборка = Справочники.Номенклатура.Выбрать();
Пока Выборка.Следующий() Цикл
	// здесь читается очередной элемент
КонецЦикла;

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

Правильный способ прочитать много — запрос. Выбрать() уместен разве что в разовой обработке по маленькому справочнику. Всё остальное делается запросом, и следующая глава как раз про него.

Что происходит при Записать()

Запись объекта — не просто сохранение полей. Платформа по дороге вызывает обработчики модуля объекта:

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

Упражнение 4. Изменить и сохранить

Напишите СменитьАртикул(Наименование, Новый): найти товар, получить объект, поставить новый артикул, записать. Вернуть артикул, прочитанный заново из базы по ссылке. Если товара нет — вернуть пустую строку.

Решается в тренажёре: код запускается и проверяется сразу.

Что дальше

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

Как закрепить

Читать про код и писать код — разные умения. В тренажёре к этой главе идут упражнения: вы пишете решение, оно запускается на настоящем интерпретаторе 1С и проверяется сразу, без установки платформы.

Открыть эту главу в тренажёре

Коллекции: где хранить много значений
Формы: клиент, сервер и управление элементами