АВТОМАТИЗАЦИЯ БИЗНЕС-ПРОЦЕССОВ НА 1С

Распространённые ошибки при программировании в 1С:Предприятие

19 октября 2022

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

Вакансии в нашу компанию: Программист 1С, Консультант 1С 

Ниже мы опишем, на наш взгляд, самые распространённые недочёты в написании кода и проектировании, а так же, дадим рекомендации по их устранению и недопущению.

1. Получение данных в цикле.

Распространенная ошибка — запрос в цикле. Многократный вызов запроса является грубой ошибкой, существенно снижающей производительность. Это происходит не только в текущем сеансе, но и затрудняет работу других пользователей (например, в случае открытой транзакции в момент выполнения кода).

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

2. Вместо параметров виртуальной таблицы использование условий "ГДЕ".

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

3. Отсутствие проверки на NULL.

При соединении таблиц в запросе необходимо предотвратить значение NULL, которое может «наделать дел» при обработке результата запроса. Как известно, значение NULL практически не пригодно к обработке: его почти не с чем сравнить, нельзя превратить в строку и т. д. По этому, когда оно попадается, то это чаще всего приводит к ошибке преобразования типов или ошибке сравнения несовместимых типов. Беда в том, что на контрольных примерах эту ошибку можно и не отловить, а на живой базе с разнообразием исходных данных она может себя показать лишь через длительное время. По этому, в запросах принято использовать ЕстьNull(), когда есть вероятность возникновения таких значений, чтобы их не допустить.

4. Получение данных не из регистра.

Самым достоверным источником информации является регистр, а не документ, как бы этого не хотелось… Например, из-за ручной операции, которая делает записи в регистр интерактивно. Иными словами, если брать данные для какого-нибудь отчёта или обработки из документа, а не из регистра, то можно столкнуться с тем, что данные в документе будут неактуальны. Это может произойти в случае, если записи регистра изменены документом «корректировка регистров» или документом закрытия месяца, который тоже иногда изменяет записи прямо у документов и т.п..

5. Остатки нельзя вывести в ноль.

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

6. Ресурсы регистра изменяются только в одну сторону.

То есть, только в «+» или только в «-«. Это приведет к переполнению таблиц итогов, что является частным случаем вышеописанной проблемы.

7. Отсутствие проверок для корректного заполнения ресурсов регистра.

Например, отсутствует проверка на остаток товара, которая поможет пользователю избежать отрицательного остатка. Из-за нехватки времени или заниженных требований качества у разработчиков иногда появляется соблазн сделать рабочий код, но не продумать защиту от неловких действий пользователя. Ситуация, когда программа работает, но «шаг влево, шаг вправо» и в регистрах копятся самые банальные косяки…

8. Нерешённая или неправильно решенная "Проблема копеек".

Пример: на остатке 3 товара стоимостью 100,00 руб. Нам нужно рассчитать стоимость списания каждого и списать.

Формула расчёта стоимости списания:

Себестоимость Остаток / Количество Остаток * Количество Списания = 33,33 * 3 = 99,99 руб.

После списания остается 0 шт и 1 копейка, что является частным случаем не вывода ресурсов регистра в ноль.

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

9. Использование информации по оборотам при получении итогов по остаткам и наоборот.

Суть ошибки заключается в неправильном использовании виртуальных таблиц регистров накопления. Если нужно получить данные остатков на момент времени, нужно использовать таблицу Остатки, а не вычислять остаток как Приход минус Расход. Если нужно получить данные за период (например, приход денег за месяц), то нужно использовать таблицу Обороты, а не ОстаткиИОбороты, чтобы не получать избыточные данные остатков, которые не будут использоваться.

10. Обращение к реальным таблицам регистра без необходимости.

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

11. Установка отборов по неиндексированным полям.

«ИНДЕКСИРОВАТЬ ПО» нужно использовать на полях виртуальной таблицы, по которым будет выполнено соединение этой виртуальной таблицы с другими таблицами. Индексирование повышает скорость соединения таблиц, но только если в виртуальной таблице достаточно большое количество записей, т.к. само построение индекса занимает некоторое время и оно нецелесообразно на небольших объёмах.

12. Не предусмотрено "движение назад".

Всегда должна быть возможность «откатить» цепочку действий в исходное положение. При отмене проведения документа, данные регистров, реквизиты документа и прочие изменения, которые произошли с проведением, должны вернуться на тот момент, как было до проведения. Таким образом, всегда можно будет посмотреть, что было с данными до каких-либо изменений.

13. Не предусмотрено перепроведение документа задним числом.

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

14. Не отработаны дубли строк в документах при проведении.

Чтобы избежать проблем с движениями, нужно заранее сгруппировать строки табличной части документа. Например, в табличной части документа расходной накладной есть первая и третья строка с 1 штукой одного и того же товара. На остатке 1 штука. На момент проверки остатков по первой строке их будет хватать. Когда алгоритм дойдет до третьей строки, на остатках уже не должно быть этого товара, но движения еще не были сформированы и ошибки не будет. В итоге движения будут некорректными. Чтобы этого избежать, нужно передать в алгоритм проведения сразу 2 штуки объединённые в одну строку.

15. Неверное соединение таблиц.

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

16. Неверное определение вида регистра накопления.

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

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

Автор Максим Багров, редактор Илья Ильин.

Подпишитесь
на статьи по 1С

    на e-mail


    send

    или в нашем блоге

    tg