При изучении основ программирования в среде 1С:Предприятие начинающие разработчики часто сталкиваются с ситуацией, когда код, который кажется синтаксически верным, отказывается работать или выдает странные ошибки в отладчике. Одной из таких классических проблем является попытка динамического формирования массива дат. Рассмотрим подробнее, почему может возникать ошибка Поле объекта не обнаружено (Добавить), и разберем правильные подходы к решению этой задачи.
Рассмотрим код, который изначально вызвал затруднение у автора:
Массив = Новый Массив;
Дата = '20231124';
НачМесяца = Дата(НачалоМесяца(Дата) - 68400);
Для Шаг = 1 по 30 Цикл
НачМесяца = НачМесяца + 86400;
Массив.Добавить(НачМесяца);
КонецЦикла;
Проанализируем этот фрагмент. На первый взгляд, здесь создается объект Массив, определяется начальная точка и в цикле Для добавляются элементы. Однако при запуске система выдает ошибку. Выясним причину, пройдя по шагам через основные архитектурные особенности платформы.
В системе 1С программный код не может существовать «сам по себе» в текстовом файле модуля. В Модуле управляемого приложения (или обычного приложения) исполняемый код, такой как создание объектов и циклы, должен обязательно располагаться внутри событийных процедур. Если написать код просто в тексте модуля (в разделе объявлений), платформа может проигнорировать его или выдать ошибку при попытке обращения к неинициализированным переменным.
Решение: Весь код необходимо обернуть в стандартную процедуру, которая служит «точкой входа». Для модуля приложения такой точкой является ПриНачалеРаботыСистемы. Рассмотрим правильную структуру:
Процедура ПриНачалеРаботыСистемы()
ДатМассив = Новый Массив;
ТекущаяДата = НачалоМесяца(ТекущаяДата());
// Логика заполнения массива
КонецПроцедуры
Часто новички пытаются проверить работу кода, используя окно «Вычислить выражение» в конфигураторе. Когда вы вводите там команду ДатМассив.Добавить(Значение), система может вернуть ошибку. Почему это происходит?
Добавить() у объекта Массив является процедурой, а не функцией. Он выполняет действие, но не возвращает никакого значения. Отладчик же ожидает получить результат для отображения.ДатМассив еще не определена (например, код не дошел до строки инициализации), попытка вызвать метод приведет к ошибке Поле объекта не обнаружено.Совет: Чтобы проверить содержимое массива в отладчике, смотрите саму переменную ДатМассив, а не вызывайте методы изменения коллекции в окне вычислений.
В исходном примере автор использовал конструкцию НачалоМесяца(Дата) - 68400. Число 68400 — это количество секунд в 19 часах. Вероятно, автор хотел «отмотать» время назад, но в 1С сутки состоят из 86400 секунд. Кроме того, функции НачалоМесяца() и КонецМесяца() уже возвращают тип Дата, поэтому дополнительное использование функции Дата() избыточно.
Рассмотрим, как правильно организовать цикл для получения всех дней месяца. Вместо фиксированного цикла Для Шаг = 1 по 30, который будет давать ошибку в месяцах, где 28 или 31 день, лучше использовать цикл Пока.
Этот способ является наиболее надежным, так как мы не зависим от количества дней в конкретном месяце.
Процедура ЗаполнитьМассивДат(ПроизвольнаяДата)
МассивДней = Новый Массив;
ДатаНачала = НачалоМесяца(ПроизвольнаяДата);
ДатаОкончания = КонецМесяца(ПроизвольнаяДата);
ВспомогательнаяДата = ДатаНачала;
Пока ВспомогательнаяДата <= ДатаОкончания Цикл
МассивДней.Добавить(ВспомогательнаяДата);
// Прибавляем ровно одни сутки (86400 секунд)
ВспомогательнаяДата = ВспомогательнаяДата + 86400;
КонецЦикла;
Сообщить("В массиве элементов: " + МассивДней.Количество());
КонецПроцедуры
Если мы все же хотим использовать цикл Для, нам нужно сначала вычислить, сколько дней в текущем месяце. Это можно сделать с помощью функции День(), примененной к концу месяца.
Дата = ТекущаяДата();
КоличествоДней = День(КонецМесяца(Дата));
Начало = НачалоМесяца(Дата);
МассивДат = Новый Массив;
Для НомерДня = 0 По КоличествоДней - 1 Цикл
МассивДат.Добавить(Начало + (НомерДня * 86400));
КонецЦикла;
Для более опытных разработчиков существует способ получения списка дат через запрос. Это полезно, когда нужно соединить календарь с данными из базы. Мы можем использовать временную таблицу с числами и функцию ДОБАВИТЬКДАТЕ.
Основные преимущества такого подхода:
Подведем итог нашему разбору. Чтобы ваш код по работе с массивами дат «взлетел», придерживайтесь следующих правил:
ПриНачалеРаботыСистемы).Массив действительно создана через Новый Массив до того, как вы начнете вызывать метод Добавить().НачалоМесяца(), КонецМесяца() и День() помогут избежать ошибок «360 дней в году».Следуя этим рекомендациям, вы сможете эффективно работать с любыми коллекциями объектов в 1С и избегать досадных ошибок на этапе старта разработки.