При разработке внешних обработок или доработке существующих форм часто возникает задача ведения простого счетчика. Например, нужно посчитать количество нажатий на кнопку или количество итераций определенного процесса. Начинающие разработчики часто сталкиваются с тем, что их счетчик «замирает» на единице и не увеличивается при повторных действиях. В этой статье мы подробно разберем, почему это происходит, и рассмотрим правильные способы реализации этой задачи в среде 1С:Предприятие 8.3 на управляемых формах.
Рассмотрим ситуацию, с которой столкнулся автор темы. В коде процедуры нажатия кнопки переменная инициализировалась прямо внутри самой процедуры:
&НаКлиенте
Процедура СчетчикНажатий(Команда)
Реквизит1 = 0;
Если Реквизит1 = 0 Тогда
Реквизит1 = Реквизит1 + 1;
КонецЕсли;
Сообщить("Количество нажатий: " + Реквизит1);
КонецПроцедуры
Проанализируем ситуацию: каждый раз, когда пользователь нажимает на кнопку, система заново заходит в процедуру СчетчикНажатий. Первая же строка Реквизит1 = 0; жестко обнуляет значение. Следовательно, при каждом выполнении кода результат всегда будет равен 1. Для решения этой проблемы нам необходимо вынести переменную за пределы процедуры, чтобы ее жизненный цикл был длиннее, чем время выполнения одного нажатия.
Первый способ — объявить переменную в разделе описания переменных модуля формы. Это позволит переменной сохранять свое значение все то время, пока форма открыта у пользователя. Рассмотрим этот вариант по шагам.
Во-первых, нам нужно объявить переменную с директивой &НаКлиенте в самом верху модуля. Во-вторых, крайне важно инициализировать её начальным значением (например, нулем) при открытии формы, иначе мы получим ошибку при попытке сложения.
&НаКлиенте
Перем КоличествоНажатий; // Переменная живет, пока открыта форма
&НаКлиенте
Процедура ПриОткрытии(Отказ)
КоличествоНажатий = 0; // Задаем начальное значение
КонецПроцедуры
&НаКлиенте
Процедура НажмиМеня(Команда)
КоличествоНажатий = КоличествоНажатий + 1;
Сообщить("Количество нажатий = " + КоличествоНажатий);
КонецПроцедуры
Важное замечание: Переменные модуля, объявленные через Перем, существуют только в оперативной памяти клиента. Если код перейдет на сервер (например, для выполнения запроса), сервер «не увидит» эту переменную. Поэтому такой способ подходит только для чисто клиентских задач.
Разберем более надежный и профессиональный метод — создание реквизита формы. В редакторе формы (вкладка «Реквизиты» в правой части конфигуратора) создадим новый реквизит, назовем его Счетчик и установим тип Число.
Преимущества этого метода:
В этом случае код будет выглядеть максимально просто, так как платформа сама инициализирует числовой реквизит нулем при создании формы:
&НаКлиенте
Процедура НажатиеКнопки(Команда)
// Обращаемся к реквизиту напрямую или через Объект (если это реквизит объекта)
Счетчик = Счетчик + 1;
Сообщить("Вы нажали на кнопку раз: " + Счетчик);
КонецПроцедуры
Выясним причину часто встречающейся ошибки, упомянутой в обсуждении. В 1С любая новая переменная, которой не присвоено значение, имеет тип Неопределено. Математическая операция вида Неопределено + 1 невозможна и вызывает аварийное завершение программы.
Чтобы избежать этого, всегда инициализируйте переменные:
ПриОткрытии на клиенте.ПриСозданииНаСервере на сервере.Число(), если есть сомнения в типе данных: Кол = Число(Кол) + 1;.Рассмотрим подробнее, как сделать работу со счетчиком более удобной для пользователя. Постоянно всплывающие окна Сообщить() могут раздражать. Проанализируем альтернативы:
1. Изменение заголовка кнопки. Мы можем выводить количество нажатий прямо на саму кнопку. Для этого в свойствах элемента формы (кнопки) нужно знать её имя.
&НаКлиенте
Процедура НажатиеКнопки(Команда)
Счетчик = Счетчик + 1;
Элементы.КнопкаСчетчик.Заголовок = "Нажато: " + Счетчик;
КонецПроцедуры
2. Использование статусной строки. Метод Состояние() выводит текст в нижнюю панель программы, не прерывая работу пользователя.
Состояние("Текущее значение счетчика: " + Счетчик);
Если ваша задача требует, чтобы счетчик не обнулялся после закрытия и повторного открытия обработки, обычные переменные и реквизиты формы не помогут. В этом случае следует использовать Хранилище настроек. Мы можем записывать текущее число при закрытии формы и считывать его при открытии, используя системные механизмы 1С для сохранения настроек пользователя.
Таким образом, выбор метода реализации счетчика зависит от ваших целей: для простых клиентских уведомлений достаточно &НаКлиенте Перем, а для серьезной логики, затрагивающей серверные вызовы, лучше всегда использовать полноценные реквизиты формы.