Первый шаг в 1С — абсолютно бесплатно.
Проведение документа: пишем движения в регистр Вот мы и подошли к самому интересному. В прошлом уроке мы создали регистр «Остатки товаров», но он стоит пустой, как склад без товаров. Сегодня мы научим документ писать в регистр. Это тот самый момент, когда учёт начинает «жить»: провели документ — и в регистре появилось движение. |
Немного теории: что такое проведение В 1С у документа есть две операции, которые часто путают новички: Запись — документ просто сохраняется в базе. Дата, номер, реквизиты — всё на месте. Но движений он не создаёт. Проведение — документ сохраняется и создаёт движения в регистрах.
Проведённый документ помечается в журнале специальной иконкой (обычно зелёной галочкой или «птичкой»). Непроведённый — пустым квадратиком или другим значком. |
|
|
Процедура ОбработкаПроведения(Отказ, РежимПроведения) // 1. Очищаем старые движения Движения.ОстаткиТоваров.Очистить(); // 2. Проходим по строкам табличной части Для Каждого Строка Из СписокТоваров Цикл // 3. Создаём новое движение Движение = Движения.ОстаткиТоваров.Добавить(); Движение.ВидДвижения = ВидДвиженияНакопления.Приход; Движение.Период = Дата; Движение.Товар = Строка.Товар; Движение.Количество = Строка.Количество; КонецЦикла; // 4. Записываем движения Движения.ОстаткиТоваров.Записывать = Истина; Движения.Записать(); КонецПроцедуры |
|
Движение.ВидДвижения = ВидДвиженияНакопления.Расход; Всё остальное — почти так же. Регистр сам вычтет расход из прихода, и остаток уменьшится. Регистр «Остатки» — это простой баланс «приход минус расход». Если вы создадите документ реализации — появится ещё одна запись в регистре накопления. |
|
Мини-итог Сегодня вы: Узнали, чем запись документа отличается от проведения. Открыли модуль объекта документа и нашли процедуру ОбработкаПроведения. Написали код, который создаёт движения в регистре при проведении. Поняли, зачем нужна Очистить() и что такое ВидДвижения. Убедились, что при перепроведении движения не дублируются, а при отмене — исчезают.
Это, пожалуй, самый важный урок из всех, что были. Именно здесь 1С превращается из «игрушки со справочниками» в настоящую учётную систему. Поздравляю — вы перешли на новый уровень! 🚀 |
|
Переходим к коду «с открытыми глазами» Добрый день! ☀️ Мы с вами прошли уже несколько практических уроков: создали свой первый справочник, настроили документ, связали их через регистр накопления и даже написали первые строчки рабочего кода. Но если быть до конца честными — всё это время мы просто повторяли действия за инструкцией, не всегда до конца понимая, как именно устроен этот код изнутри. И знаете что? Это абсолютно нормально! Мы познакомились с объектами Конфигурации 1С. Теперь настало время сделать следующий шаг — погрузиться в сам код. В этой главе мы: • Изучим базовый синтаксис встроенного языка 1С. • Разберем строгие правила написания программного кода. • Познакомимся с ключевыми операторами, переменными и логическими конструкциями. После этого раздела вы перестанете бездумно копировать готовые листинги и начнете осознанно писать логику для своих собственных задач. Поехали! |
1. Модули: где живёт код и почему именно там В платформе 1С программный код размещается в строго определенных местах — модулях. Новички часто не понимают: почему в одном месте код работает, а в другом — нет? Ответ: потому что модули разные, и у каждого — свои правила.
Какие модули мы уже встречали: Модуль объекта - Внутри документа/справочника. В них пишется логика самого объекта: проведение, заполнение, проверки. Модуль формы - Внутри формы. В них пишется логика интерфейса: нажатия кнопок, изменения полей. |
2. Контекст выполнения: почему «здесь видно, а там нет» В 1С есть такое понятие — контекст. Это «набор всего, что доступно в данном месте кода». В модуле объекта документа контекст включает: реквизиты документа, табличные части, Движения, ЭтотОбъект. В модуле формы контекст включает: Элементы формы, реквизиты формы, ЭтаФорма. Почему это важно? Потому что при написании кода нужно всегда спрашивать себя: «А в каком модуле я нахожусь? Что мне тут доступно?» . Главное правило: код видит только то, что доступно в его модуле.
|
2. Директивы компиляции: &НаКлиенте, &НаСервере На уроке 0.2 мы писали: &НаКлиенте Процедура Поздороваться(Команда) Сообщить("Hello, World!"); КонецПроцедуры Что это за &НаКлиенте? Это директива компиляции. Она говорит 1С: «Эта процедура выполняется на компьютере пользователя». В чём суть: Клиент — это компьютер пользователя. Тут живут формы, кнопки, интерфейс. Сервер — это мощный компьютер, где живет база данных (таблицы, документы, тяжелые расчеты). Они общаются друг с другом по сети, и гонять между ними лишние данные — дорого и долго. В 1С код может выполняться либо на клиенте, либо на сервере. Нельзя просто так взять и обратиться к базе данных с клиента — нужно «сходить» на сервер.
Директивы бывают: &НаКлиенте — только на клиенте. &НаСервере — только на сервере, но с доступом к реквизитам формы. Когда вы вызываете процедуру с этой директивой, платформа берет всю форму целиком, упаковывает и тащит по сети на сервер. • Плюсы: Полный комфорт. Доступны любые данные формы (можно написать ЭтотОбъект.Дата или просто Объект.Контрагент), и изменения сразу отобразятся на экране у пользователя. • Минусы: Это самый «тяжелый» и медленный вызов. Если форма огромная (например, накладная на 10 000 строк), гонять ее туда-обратно по сети ради пустяковой операции — преступление против производительности. &НаСервереБезКонтекста — на сервере, но без доступа к форме. При таком вызове форма остается на клиенте. Платформа идет на сервер «голой». На сервере в этот момент недоступны данные формы напрямую (нельзя написать Объект.Склад, будет ошибка). Если серверу нужны какие-то данные для расчетов, вы должны передать их вручную через параметры процедуры. • Плюсы: Работает молниеносно. По сети передаются только те крупицы данных, которые вы сами указали. • Минусы: Нельзя напрямую менять реквизиты формы. Если сервер что-то посчитал, он должен вернуть результат через Возврат, а вы на клиенте уже сами решите, в какое поле формы его записать. &НаКлиентеНаСервереБезКонтекста — и там, и там (с ограничениями). Этот код компилируется и на клиенте, и на сервере. Эта директива используется в основном для служебных, математических или текстовых функций. Особенности данной директивы пока не рассмотрим. Главное правило разработчика 1С: Всегда выбирайте &НаСервереБезКонтекста, если вам нужно просто сходить в базу данных (что-то найти, проверить) и для этого не требуется вся форма целиком. Переходите на обычное &НаСервере только тогда, когда без контекста формы физически не обойтись. А для модуля объекта, где весь код живёт на сервере, указывать директивы вообще не нужны — по умолчанию модуль объекта «серверный».
|
3. Переменные: коробочки для значений В предыдущих уроках мы использовали понятие Переменной. Зачем она нужна? Чтобы хранить промежуточный результат вычислений. Переменная в 1С — это именованная «коробочка», в которой лежит значение. Имя переменной может содержать буквы (русские и латинские), цифры и знак подчеркивания _. Имя не может начинаться с цифры. Рекомендуется давать осмысленные (например, ТекущийКонтрагент, КоличествоСтрок); 1С поддерживает два вида объявления переменных: явное (через ключевое слово Перем) и неявное (при первом присваивании). // Явное объявление переменной Перем Х3, Х4, Х5; // Не явное объявление переменной Х1 = 4; В большинстве случаев переменные не обязательно объявлять заранее. Неявным созданием переменной считается первое появление её имени в левой части оператора присваивания (=). • Изначально ей присваивается значение Неопределено. • Тип переменной определяется динамически по типу записанного в нее значения. При явном объявлении переменной, используется зарезервированное слово - Перем, после чего указывается имя переменной (или несколько имен через запятую), а в конце ставится точка с запятой ; |
4. Процедуры и функции: зачем разбивать код на куски Процедура — это именованный блок кода, который можно вызывать. Функция — то же самое, но она возвращает результат. Процедура: Процедура Поздороваться() Сообщить("Привет!"); КонецПроцедуры Функция: Функция Удвоить(Число) Возврат Число * 2; КонецФункции Зачем это нужно? Чтобы не повторять один и тот же код много раз. Чтобы код был понятнее: одна процедура — одна задача. Чтобы можно было переиспользовать логику в разных местах.
Кстати, те заготовки, которые 1С сама создаёт (ОбработкаПроведения, СписокТоваровЦенаПриИзменении) — это тоже процедуры. Просто их вызывает не вы, а сама платформа, когда наступает нужное событие. Такие процедуры называются обработчиками событий. У оператора Возврат две главные задачи в коде: 1. Для Функций (использование обязательно): Он возвращает результат вычислений туда, откуда функция была вызвана, и мгновенно завершает её работу. 2. Для Процедур (использование опционально): Он используется без параметров, просто чтобы досрочно завершить выполнение процедуры и выйти из неё, если дальнейший код выполнять не нужно. Пример. Функция ВычислитьСуммуСНДС(СуммаБезНДС)
Результат = СуммаБезНДС * 1.20;
// Оператор возвращает число и завершает работу функции Возврат Результат;
// Этот код ниже НИКОГДА не выполнится: Сообщить("Этот текст никто не увидит");
КонецФункции Процедура ПроверитьЗаполнениеСклада(ДокументОбъект)
// Если склад уже заполнен, делать проверку не нужно Если ЗначениеЗаполнено(ДокументОбъект.Склад) Тогда Возврат; // Оператор просто прерывает процедуру прямо здесь КонецЕсли;
// Код ниже выполнится только в том случае, если склад ПУСТОЙ ВызватьИсключение "Поле 'Склад' обязательно для заполнения!";
КонецПроцедуры |
5. Типы данных: из чего сделаны все значения В 1С у каждого значения есть тип. Тип — это «порода» данных: число, строка, дата и так далее. От типа зависит, что с этим значением можно делать. Основные типы, которые вы уже встречали: Число - Числа, целые и дробные. Примеры: 2500, 3.5, 0 Строка -Текст в кавычках. Примеры:"Чайник", "Hello, World!" Дата - Дата и время. Примеры: '20250101', ТекущаяДата() Булево - Истина или Ложь. Примеры: Истина, Ложь Ссылка - Ссылка на объект (элемент справочника, документ и т.д.). Пример Справочники.Товары.НайтиПоНаименованию("Чайник") Неопределено - «Пустое» значение, когда ничего нет. Null Пустое значение из базы данных (отдельная история).
Почему это важно. Если вы попытаетесь сложить строку с числом — 1С может либо выдать ошибку, либо сделать что-то не то. Тип определяет, что можно, а что нельзя.
Как узнать тип значения программно? Есть функция ТипЗнч(): Значение = 2500; Сообщить(ТипЗнч(Значение)); // Выведет: Число А ещё можно проверить тип через конструкцию Если ТипЗнч(Значение) = Тип("Число") Тогда.... Но пока это не критично — просто знайте, что механизм есть.
💡 Запомните: тип — это «родословная» значения. Она определяет, какие операции допустимы, а какие приведут к ошибке.
|
6. Синтаксис: почему всё так «по-русски» 1С — один из немногих языков, где ключевые слова на русском. Это сначала кажется странным, а потом становится удобным (особенно когда читаешь чужой код). Почему именно так? Так задумано авторами платформы. Логика: код должен читаться почти как русский текст. Спорно, но привыкаешь быстро.
Главные правила: * Каждая команда заканчивается точкой с запятой. Забыли — ошибка. 1С строгая. Сообщить("Привет"); // Точка с запятой — обязательна * Комментарии начинаются с //. Всё, что после них до конца строки, 1С игнорирует, а для программистов это информация, позволяющая не забыть важную информацию. // Это комментарий, тут можно писать что угодно |
Условные операторы Условные операторы в 1С 8.3 используются для управления ходом выполнения программы в зависимости от истинности или ложности определенных условий. * Условный оператор Если...Тогда...КонецЕсли Этот оператор проверяет логическое условие. Если оно истинно (Истина), выполняется блок кода, следующий за словом Тогда. Если СуммаДокумента > 100000 Тогда Сообщить("Предоставить клиенту максимальную скидку!"); КонецЕсли; Форма с альтернативой (Иначе) Применяется, когда при соблюдении условия нужно сделать одно действие, а при несоблюдении — другое. Если СтатусДокумента = Перечисления.СтатусыДокументов.Проведен Тогда РазрешитьРедактирование = Ложь; Иначе РазрешитьРедактирование = Истина; КонецЕсли; Множественные условия (ИначеЕсли) Используется для последовательной проверки нескольких разных условий. Как только одно из них оказывается истинным, выполняются связанные с ним команды, а остальные проверки пропускаются. Если Оценка = 5 Тогда Результат = "Отлично"; ИначеЕсли Оценка = 4 Тогда Результат = "Хорошо"; ИначеЕсли Оценка = 3 Тогда Результат = "Удовлетворительно"; Иначе Результат = "Неудовлетворительно"; КонецЕсли;
Логические операторы в условиях Чтобы строить сложные (составные) условия, внутри оператора Если используются логические операторы: • И (Логическое И): Условие истинно, только если истинны все его части. • ИЛИ (Логическое ИЛИ): Условие истинно, если истинна хотя бы одна из его частей. • НЕ (Логическое НЕ): Инвертирует (переворачивает) результат (делает Истина из Ложь и наоборот). Пример составного условия: Если (РольДоступна("ПолныеПрава") ИЛИ ЭтоНовыйДокумент) И НЕ ДокументЗаблокирован Тогда // Код для выполнения КонецЕсли;
Сокращенный условный оператор в коде Встроенный язык 1С позволяет записывать простые условия «Если-Тогда-Иначе» в одну строку. Для этого используется встроенная функция ?(). Результат = ?(Условие, ЗначениеЕслиИстина, ЗначениеЕслиЛожь); Понятный пример из практики. Представим задачу: у нас есть переменная КоличествоТовара. Если на складе 0 штук, мы хотим вывести статус «Нет в наличии», а если больше нуля — «Доступен». //Как бы мы писали это через обычное «Если»: ПеременнаяСтатус = ""; Если КоличествоТовара = 0 Тогда ПеременнаяСтатус = "Нет в наличии"; Иначе ПеременнаяСтатус = "Доступен"; КонецЕсли; // Как это пишется через сокращенный оператор ПеременнаяСтатус = ?(КоличествоТовара = 0, "Нет в наличии", "Доступен");
Проверка на Пустую ссылку. В платформе 1С:Предприятие пустая ссылка — это специальное значение для реквизитов ссылочного типа (справочники, документы, процессы), которое показывает, что поле ни на что не указывает. Ее можно сравнить с «пустой ячейкой», у которой уже определен тип данных, но самого элемента внутри нет. Пустые ссылки возвращаются в случае, когда объект не найден методами: НайтиПоНаименованию(), НайтиПоКоду(), НайтиПоНомеру(). Пустые ссылки являются значениями по умолчанию для реквизитов ссылочных типов. Если реквизит имеет составной тип данных, то значением по умолчанию для него является Неопределено. Проверить на пустую ссылку можно так: Если Ссылка.Пустая() Тогда //Или так: Если Ссылка = Справочники.Номенклатура.ПустаяСсылка() Тогда Понятный пример из практики. Представим задачу: нам нужно программно найти товар по коду и, если он существует, изменить его цену. Если товара нет — выдать предупреждение. // Пытаемся найти товар на складе по коду ТоварСсылка = Справочники.Номенклатура.НайтиПоКоду("00-000123"); // Проверяем, нашелся ли товар Если ТоварСсылка.Пустая() Тогда
Сообщить("Внимание! Товар с кодом 00-000123 не найден в системе.");
Иначе //Получаем объект для редактирования ТоварОбъект = ТоварСсылка.ПолучитьОбъект(); ТоварОбъект.Цена = 1500; ТоварОбъект.Записать();
КонецЕсли;
|
| 7. Циклы в 1С: Как автоматизировать повторяющиеся действия Цикл — это конструкция кода, которая позволяет выполнять одну и ту же последовательность команд множество раз, пока соблюдается определенное условие. В языке 1С есть три вида циклов. Каждый из них идеально подходит под свою задачу.
1. Цикл «Для каждого» (Для обхода коллекций) Это самый популярный цикл в 1С. Он используется, когда у вас есть готовый набор данных (коллекция) и вам нужно по очереди перебрать все элементы внутри него. Что можно обходить: строки табличной части документа, строки таблицы значений, массивы, структуры. Синтаксис:
Для Каждого ТекущийЭлемент Из КоллекцияДанных Цикл
// Код обработки ТекущегоЭлемента КонецЦикла; Пример из практики: Считаем сумму товаров в документе Представим, что у нас есть документ «Реализация товаров», и нам нужно вручную посчитать общую сумму по всем строкам его табличной части Товары. ОбщаяСуммаДокумента = 0; // Обходим каждую строку в табличной части "Товары" Для Каждого СтрокаТовара Из Товары Цикл
// Прибавляем сумму текущей строки к общему итогу ОбщаяСуммаДокумента = ОбщаяСуммаДокумента + СтрокаТовара.Сумма;
КонецЦикла; Сообщить("Итоговая сумма по документу: " + ОбщаяСуммаДокумента);
2. Цикл «По счетчику» (Для фиксированного числа повторений) Этот цикл используется, когда вы заранее точно знаете, сколько раз (например, ровно 10 или 50 раз) нужно выполнить код. В нем используется переменная-счетчик, которая автоматически увеличивается на 1 на каждом шаге (итерации). Синтаксис: Для Счетчик = НачальноеЗначение По КонечноеЗначение Цикл // Код, который выполнится фиксированное число раз КонецЦикла; Пример из практики: Генерация номеров или периодов Допустим, нам нужно вывести в консоль список месяцев на год вперед для планирования. // Цикл выполнится ровно 12 раз (от 1 до 12) Для НомерМесяца = 1 По 12 Цикл
Сообщить("Планирование на месяц № " + НомерМесяца);
КонецЦикла; 3. Цикл «Пока» (С предусловием) Этот цикл работает до тех пор, пока истинно заданное вами условие. Если условие изначально ложно, цикл не выполнится ни разу. Важно: внутри цикла обязательно должно происходить действие, которое рано или поздно нарушит условие, иначе программа «зависнет» (уйдет в бесконечный цикл). Синтаксис: Пока УсловиеВыполнения Цикл // Код, который работает, пока УсловиеВыполнения = Истина КонецЦикла; Пример из практики: Чтение данных из выборки БД Классический пример использования цикла Пока — это обход результатов запроса или выборки элементов справочника с помощью метода .Следующий(). // Получаем выборку всех элементов справочника "Склады" ВыборкаСкладов = Справочники.Склады.Выбрать(); // Метод Следующий() возвращает Истина, если есть следующий элемент, // и Ложь, если элементы закончились. Пока ВыборкаСкладов.Следующий() Цикл
// Выводим наименование текущего склада Сообщить("Найден склад: " + ВыборкаСкладов.Наименование);
КонецЦикла;
Инструменты управления циклом: Прервать и Продолжить Иногда логику цикла нужно изменить прямо «на лету». Для этого есть две специальные команды: • Прервать — полностью останавливает цикл и выводит программу из него. Удобно, если вы искали конкретный элемент и уже нашли его — дальше крутить цикл нет смысла. • Продолжить — мгновенно прекращает текущий шаг (итерацию) и переходит к началу следующего шага. Используется, чтобы пропустить обработку «неподходящих» элементов. Пример использования операторов управления: Для Каждого Строка Из ТЧТовары Цикл
// Пропускаем услуги, нам нужны только материальные товары Если Строка.ЭтоУслуга Тогда Продолжить; // Цикл бросит эту строку и сразу перейдет к следующей КонецЕсли;
// Если нашли критическую ошибку в данных, полностью останавливаем проверку Если Строка.Количество < 0 Тогда Сообщить("Критическая ошибка! Количество не может быть отрицательным."); Прервать; // Цикл полностью завершает работу КонецЕсли;
// Тут идет стандартная обработка товара...
КонецЦикла; |
Мини-итог Сегодня вы: Узнали, что такое модули и почему код работает не везде одинаково. Познакомились с контекстом и директивами компиляции. Вспомнили, что такое переменные и зачем они. Осознали разницу между процедурой и функцией. Разобрались с типами данных — Число, Строка, Дата, Булево, Ссылка. Углубились в изучение синтаксиса 1С. Подробно разобрались с Условными операторами. С методами проверки на Пустую ссылку. Подробно разобрались с Циклами. |
