1C-Code → Основы 1С → Справочники и документы: чтение и запись
Здесь кончается «просто язык» и начинается сама 1С: ссылка, объект, запись и проведение.
Глава 11 из 36 · чтение примерно 30 минут
Всё, что было до сих пор, — обычное программирование: переменные, условия, циклы, коллекции. Такое есть в любом языке.
С этой главы начинается то, ради чего 1С существует: работа с данными учёта. Справочники, документы, чтение и запись.
Справочник — список того, что существует само по себе и живёт долго: номенклатура, контрагенты, склады, сотрудники. Элемент справочника не привязан ко времени.
Документ — событие, случившееся в определённый момент: реализация, поступление, оплата. У документа всегда есть дата и номер, и он меняет учётные итоги, когда его проводят.
Разница не формальная. Если сущность отвечает на вопрос «что это» — справочник. Если на вопрос «что произошло и когда» — документ.
Это ключевое понятие 1С.
Когда вы находите элемент справочника, вы получаете не сам элемент, а ссылку на него. Ссылка — это адрес, указатель на запись в базе. Сама по себе она почти ничего не весит.
А вот когда вы пишете Товар.Артикул, платформа идёт по этому адресу в базу и читает реквизит. Каждое обращение через точку — отдельное чтение.
Читайте точку вслух как «сходить в базу»
Приём, который экономит годы: читая Ссылка.Реквизит, проговаривайте про себя «сходить в базу за реквизитом».
Тогда строка СтрокаФайла.Товар.Поставщик.Регион внутри цикла сразу читается как «три похода в базу на каждой строке документа» — и становится видно, почему это медленно.
В запросе точка ведёт себя иначе: там она превращается в соединение, и лишних обращений не создаёт. Но об этом — в главе про запросы.
Товар = Справочники.Номенклатура.НайтиПоНаименованию("Гвозди 100мм");
Если Не ЗначениеЗаполнено(Товар) Тогда
Возврат "не найден";
КонецЕсли;
Возврат Товар.Артикул;
| Часть | Что означает |
|---|---|
Справочники | общая точка входа ко всем справочникам конфигурации |
.Номенклатура | имя конкретного справочника — как он назван в конфигурации |
НайтиПоНаименованию | вернёт ссылку или ПУСТУЮ ссылку, если не нашлось |
ЗначениеЗаполнено | проверка перед использованием — обязательна |
Товар.Артикул | вот здесь и происходит чтение из базы |
Не нашлось — это не ошибка, а пустая ссылка
НайтиПоНаименованию не падает, когда ничего не нашла. Она возвращает пустую ссылку — ссылку, которая никуда не ведёт.
Падение случится строкой ниже, на Товар.Артикул: обращение к реквизиту несуществующего элемента. И в сообщении будет указана эта строка, а не та, где на самом деле проблема.
Поэтому результат поиска проверяют сразу, через ЗначениеЗаполнено. Каждый раз, без исключений — даже когда «этот товар точно есть в базе».
Упражнение 1. Артикул по наименованию
Напишите функцию Артикул(Наименование): найти товар в справочнике Номенклатура и вернуть его артикул. Если товара нет — вернуть пустую строку. Проверка спрашивает несуществующий товар и ждёт пустую строку.
Решается в тренажёре: код запускается и проверяется сразу.
По ссылке можно только читать. Чтобы что-то изменить, нужен объект — он получается вызовом ПолучитьОбъект().
Разница принципиальна и по смыслу, и по цене: ссылка легка, а объект — это вся запись, поднятая из базы в память, вместе со всеми реквизитами и табличными частями.
✓ Ссылка — читать
Товар = Справочники.Номенклатура
.НайтиПоНаименованию("Гвозди 100мм");
Сообщить(Товар.Артикул);
// Товар.Артикул = "НОВЫЙ"; ← так нельзяДёшево. Так работают, когда данные только читают.
✕ Объект — менять
Объект = Товар.ПолучитьОбъект();
Объект.Артикул = "НОВЫЙ";
Объект.Записать();Дороже: подняли всю запись. Зато можно менять и записывать.
| Задача | Как |
|---|---|
| найти по имени | Справочники.Х.НайтиПоНаименованию("…") |
| найти по коду | Справочники.Х.НайтиПоКоду("…") |
| найти документ | Документы.Х.НайтиПоНомеру("…") |
| создать новый элемент | Справочники.Х.СоздатьЭлемент() |
| создать документ | Документы.Х.СоздатьДокумент() |
| получить изменяемый объект | Ссылка.ПолучитьОбъект() |
| сохранить изменения | Объект.Записать() |
| провести документ | Объект.Записать(РежимЗаписиДокумента.Проведение) |
| проверить, что нашлось | ЗначениеЗаполнено(Ссылка) |
Новый элемент создают методом СоздатьЭлемент(). Он сразу возвращает объект — ссылки ещё нет, потому что в базе ничего нет.
Ссылка появится только после Записать(). До этого момента элемент существует лишь в памяти, и если программа прервётся — не останется ничего.
Объект = Справочники.Номенклатура.СоздатьЭлемент();
Объект.Наименование = "Саморезы 50мм";
Объект.Артикул = "СМ-50";
Объект.Записать();
Возврат Объект.Ссылка; // ссылка появилась только сейчас
| Часть | Что означает |
|---|---|
СоздатьЭлемент | сразу объект: создаём то, чего в базе ещё нет |
Наименование | обычное присваивание — объект можно менять |
Записать() | вот здесь запись реально попадает в базу |
Объект.Ссылка | до Записать() ссылки нет — и хранить её негде |
Упражнение 2. Завести товар
Напишите ЗавестиТовар(Наименование): создать элемент справочника Номенклатура, заполнить наименование, записать и вернуть наименование записанного элемента через его ссылку.
Решается в тренажёре: код запускается и проверяется сразу.
У документа кроме обычных реквизитов (дата, номер, контрагент) есть табличные части — вложенные таблицы. У реализации это обычно Товары: строка на каждую позицию.
Обходят её как обычную коллекцию, циклом Для Каждого. Каждая строка — набор своих реквизитов: номенклатура, количество, цена, сумма.
Ссылка = Документы.РеализацияТоваров.НайтиПоНомеру("000001");
Объект = Ссылка.ПолучитьОбъект();
Результат = 0;
Для Каждого СтрокаФайла Из Объект.Товары Цикл
Результат = Результат + СтрокаФайла.Сумма;
КонецЦикла;
| Часть | Что означает |
|---|---|
Объект.Товары | имя табличной части — как она названа в конфигурации |
Стр | строка табличной части, у неё свои реквизиты |
Стр.Сумма | реквизит строки, а не документа |
зачем объект | здесь он взят, чтобы менять; только для чтения хватило бы запроса |
Упражнение 3. Сумма по строкам документа
Напишите ИтогДокумента(Номер): найти документ РеализацияТоваров по номеру, сложить Сумма по всем строкам табличной части Товары. Если документа нет — вернуть 0. Проверка передаёт номер 000001.
Решается в тренажёре: код запускается и проверяется сразу.
Записать() у документа просто сохраняет его. Учётные итоги при этом не меняются: документ лежит в базе, но остатки и обороты его не видят.
Меняет итоги проведение: Записать(РежимЗаписиДокумента.Проведение). Только тогда документ формирует движения по регистрам — товар списывается со склада, долг появляется у контрагента.
Отсюда классическая жалоба «отчёт не видит документ». Документ есть, он записан — просто не проведён.
Читать много объектов циклом — почти всегда ошибка
У менеджера есть метод Выбрать(), дающий выборку по всем элементам:
Выборка = Справочники.Номенклатура.Выбрать();
Пока Выборка.Следующий() Цикл
// здесь читается очередной элемент
КонецЦикла;Работает — но это чтение всей таблицы по одной записи, без отбора, без сортировки, без возможности сразу соединить с другими данными.
Правильный способ прочитать много — запрос. Выбрать() уместен разве что в разовой обработке по маленькому справочнику. Всё остальное делается запросом, и следующая глава как раз про него.
Что происходит при Записать()
Запись объекта — не просто сохранение полей. Платформа по дороге вызывает обработчики модуля объекта:
Отказ = Истина отменяет запись целиком;Отсюда правило: проверки ставят в ПередЗаписью, а не в форме. Форма — не единственный путь к данным: есть обмен, есть обработки, есть другой код. Проверка в форме защищает только от человека, который вводит вручную.
Упражнение 4. Изменить и сохранить
Напишите СменитьАртикул(Наименование, Новый): найти товар, получить объект, поставить новый артикул, записать. Вернуть артикул, прочитанный заново из базы по ссылке. Если товара нет — вернуть пустую строку.
Решается в тренажёре: код запускается и проверяется сразу.
Вы умеете находить, читать, менять и записывать данные поштучно. Следующая глава — язык запросов: как получать данные сразу пачками, с отбором, группировкой и соединением таблиц. Это то, чем в 1С читают всё, что больше одного объекта.
Читать про код и писать код — разные умения. В тренажёре к этой главе идут упражнения: вы пишете решение, оно запускается на настоящем интерпретаторе 1С и проверяется сразу, без установки платформы.
← Коллекции: где хранить много значений
→ Формы: клиент, сервер и управление элементами