Создание калькулятора программным способом в 1С
В этой статье мы рассмотрим создание калькулятора программным способом в 1С. Для реализации мы будем использовать три основных механизма работы с формой:
1. Реквизиты формы:
- Создание реквизита для хранения результата вычислений через конструктор РеквизитФормы
- Добавление реквизита в форму методом ИзменитьРеквизиты
2. Элементы формы трех типов:
- ПолеФормы
- для отображения результата вычислений
- ГруппаФормы
- для визуальной организации кнопок калькулятора
- КнопкаФормы
- для создания кнопок с цифрами и операциями
3. Команды формы:
- Создание команд для обработки нажатий кнопок через Команды.Добавить
- Привязка команд к кнопкам и создание обработчиков
Особенность данного подхода в том, что весь интерфейс калькулятора создается программно в процедуре ПриСозданииНаСервере
, без использования конструктора форм. Это демонстрирует механизмы динамического создания и настройки элементов управления, а также принципы связывания данных, визуальных элементов и команд между собой.
Рассмотрим подробно каждый механизм и его реализацию.
Реквизиты формы являются основой для хранения данных на форме. В нашем случае нам нужен один реквизит для хранения результата вычислений. Важно понимать, что реквизит нужно сначала создать, а затем добавить в форму. После этого к нему можно обращаться через ЭтаФорма
:
// 1. Создаем описание типа для реквизита - в нашем случае строка,
// так как будем хранить как числа, так и операторы
РеквизитРезультат = Новый РеквизитФормы(
"Результат", // Имя реквизита
Новый ОписаниеТипов("Строка") // Тип реквизита
);
// 2. Добавляем реквизит в форму
МассивРеквизитов = Новый Массив;
МассивРеквизитов.Добавить(РеквизитРезультат);
ИзменитьРеквизиты(МассивРеквизитов);
// 3. После этого реквизит становится доступен через ЭтаФорма.Результат
Следующим шагом нам необходимо создать элементы формы для отображения данных и взаимодействия с пользователем. Начнем с поля ввода для отображения результата и группы для организации кнопок. Группа позволит нам расположить кнопки в нужном порядке и правильно их выровнять:
// 1. Создаем поле ввода для отображения результата
ПолеРезультат = Элементы.Добавить("ПолеРезультат", Тип("ПолеФормы"));
ПолеРезультат.Вид = ВидПоляФормы.ПолеВвода;
ПолеРезультат.ПутьКДанным = "Результат"; // Привязываем к реквизиту
ПолеРезультат.ТолькоПросмотр = Истина; // Запрещаем ручной ввод
// 2. Создаем группу для кнопок - все кнопки будут выстроены горизонтально
ГруппаКнопок = Элементы.Добавить("ГруппаКнопок1", Тип("ГруппаФормы"));
ГруппаКнопок.Вид = ВидГруппыФормы.ОбычнаяГруппа;
ГруппаКнопок.Группировка = ГруппировкаПодчиненныхЭлементовФормы.Горизонтальная;
ГруппаКнопок.Отображение = ОтображениеОбычнойГруппы.Нет; // Убираем визуальное оформление группы
И наконец, самая важная часть интерфейса - кнопки калькулятора. Для каждой кнопки нам нужно создать команду, которая будет обрабатывать нажатие, создать саму кнопку и связать их между собой. Затем определить процедуру-обработчик, которая будет выполняться при нажатии:
// 1. Создаем команду для кнопки
НоваяКоманда = Команды.Добавить("Кнопка1");
НоваяКоманда.Действие = "Кнопка1"; // Имя процедуры-обработчика
// 2. Создаем кнопку и привязываем к команде
НоваяКнопка = Элементы.Добавить("Кнопка1", Тип("КнопкаФормы"), ГруппаКнопок);
НоваяКнопка.ИмяКоманды = "Кнопка1";
НоваяКнопка.Заголовок = "1";
// 3. Создаем обработчик нажатия
&НаКлиенте
Процедура Кнопка1(Команда)
// При нажатии добавляем цифру 1 к строке результата
ЭтаФорма.Результат = ЭтаФорма.Результат + "1";
КонецПроцедуры
Скачать файл
Полный код решения:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ)
// Устанавливаем заголовок формы
ЭтаФорма.АвтоЗаголовок = Ложь;
ЭтаФорма.Заголовок = "Калькулятор програмно";
// ===============================
// Создание реквизита для хранения результата вычислений
// ===============================
РеквизитРезультат = Новый РеквизитФормы("Результат", Новый ОписаниеТипов("Строка"));
МассивРеквизитов = Новый Массив;
МассивРеквизитов.Добавить(РеквизитРезультат);
ИзменитьРеквизиты(МассивРеквизитов);
// ===============================
// Создание поля для отображения результата
// ===============================
ПолеРезультат = Элементы.Добавить("ПолеРезультат", Тип("ПолеФормы"));
ПолеРезультат.Вид = ВидПоляФормы.ПолеВвода;
ПолеРезультат.ПутьКДанным = "Результат"; // Привязываем к реквизиту
ПолеРезультат.ТолькоПросмотр = Истина; // Запрещаем ручной ввод
ПолеРезультат.Ширина = 20;
// ===============================
// Создание групп кнопок калькулятора
// ===============================
// Первая строка: стрелка, C, +/-, %, 1/x
ГруппаКнопок = Элементы.Добавить("ГруппаКнопок1", Тип("ГруппаФормы"));
ГруппаКнопок.Вид = ВидГруппыФормы.ОбычнаяГруппа;
ГруппаКнопок.Группировка = ГруппировкаПодчиненныхЭлементовФормы.Горизонтальная;
ГруппаКнопок.Отображение = ОтображениеОбычнойГруппы.Нет;
ГруппаКнопок.ОтображатьЗаголовок = Ложь;
ДобавитьКнопкуКалькулятора(ГруппаКнопок, "←", "КнопкаУдалить");
ДобавитьКнопкуКалькулятора(ГруппаКнопок, "C", "КнопкаОчистить");
ДобавитьКнопкуКалькулятора(ГруппаКнопок, "+/-", "КнопкаЗнак");
ДобавитьКнопкуКалькулятора(ГруппаКнопок, "%", "КнопкаПроцент");
ДобавитьКнопкуКалькулятора(ГруппаКнопок, "1/x", "КнопкаДробь");
// Вторая строка: 7 8 9 / *
ГруппаКнопок = Элементы.Добавить("ГруппаКнопок2", Тип("ГруппаФормы"));
ГруппаКнопок.Вид = ВидГруппыФормы.ОбычнаяГруппа;
ГруппаКнопок.Группировка = ГруппировкаПодчиненныхЭлементовФормы.Горизонтальная;
ГруппаКнопок.Отображение = ОтображениеОбычнойГруппы.Нет;
ГруппаКнопок.ОтображатьЗаголовок = Ложь;
ДобавитьКнопкуКалькулятора(ГруппаКнопок, "7", "Кнопка7");
ДобавитьКнопкуКалькулятора(ГруппаКнопок, "8", "Кнопка8");
ДобавитьКнопкуКалькулятора(ГруппаКнопок, "9", "Кнопка9");
ДобавитьКнопкуКалькулятора(ГруппаКнопок, "/", "КнопкаДеление");
ДобавитьКнопкуКалькулятора(ГруппаКнопок, "*", "КнопкаУмножение");
// Третья строка: 4 5 6 + -
ГруппаКнопок = Элементы.Добавить("ГруппаКнопок3", Тип("ГруппаФормы"));
ГруппаКнопок.Вид = ВидГруппыФормы.ОбычнаяГруппа;
ГруппаКнопок.Группировка = ГруппировкаПодчиненныхЭлементовФормы.Горизонтальная;
ГруппаКнопок.Отображение = ОтображениеОбычнойГруппы.Нет;
ГруппаКнопок.ОтображатьЗаголовок = Ложь;
ДобавитьКнопкуКалькулятора(ГруппаКнопок, "4", "Кнопка4");
ДобавитьКнопкуКалькулятора(ГруппаКнопок, "5", "Кнопка5");
ДобавитьКнопкуКалькулятора(ГруппаКнопок, "6", "Кнопка6");
ДобавитьКнопкуКалькулятора(ГруппаКнопок, "+", "КнопкаСложение");
ДобавитьКнопкуКалькулятора(ГруппаКнопок, "-", "КнопкаВычитание");
// Четвертая строка: 1 2 3 . =
ГруппаКнопок = Элементы.Добавить("ГруппаКнопок4", Тип("ГруппаФормы"));
ГруппаКнопок.Вид = ВидГруппыФормы.ОбычнаяГруппа;
ГруппаКнопок.Группировка = ГруппировкаПодчиненныхЭлементовФормы.Горизонтальная;
ГруппаКнопок.Отображение = ОтображениеОбычнойГруппы.Нет;
ГруппаКнопок.ОтображатьЗаголовок = Ложь;
ДобавитьКнопкуКалькулятора(ГруппаКнопок, "1", "Кнопка1");
ДобавитьКнопкуКалькулятора(ГруппаКнопок, "2", "Кнопка2");
ДобавитьКнопкуКалькулятора(ГруппаКнопок, "3", "Кнопка3");
ДобавитьКнопкуКалькулятора(ГруппаКнопок, ".", "КнопкаТочка");
ДобавитьКнопкуКалькулятора(ГруппаКнопок, "=", "КнопкаРавно");
// Пятая строка: 0 00
ГруппаКнопок = Элементы.Добавить("ГруппаКнопок5", Тип("ГруппаФормы"));
ГруппаКнопок.Вид = ВидГруппыФормы.ОбычнаяГруппа;
ГруппаКнопок.Группировка = ГруппировкаПодчиненныхЭлементовФормы.Горизонтальная;
ГруппаКнопок.Отображение = ОтображениеОбычнойГруппы.Нет;
ГруппаКнопок.ОтображатьЗаголовок = Ложь;
ДобавитьКнопкуКалькулятора(ГруппаКнопок, "0", "Кнопка0");
ДобавитьКнопкуКалькулятора(ГруппаКнопок, "00", "КнопкаДваНуля");
КонецПроцедуры
// Вспомогательная процедура для создания кнопки калькулятора
&НаСервере
Процедура ДобавитьКнопкуКалькулятора(Родитель, Текст, ИмяКнопки)
// Создаем команду для кнопки
НоваяКоманда = Команды.Добавить(ИмяКнопки);
НоваяКоманда.Действие = ИмяКнопки;
// Создаем кнопку и связываем её с командой
НоваяКнопка = Элементы.Добавить(ИмяКнопки, Тип("КнопкаФормы"), Родитель);
НоваяКнопка.ИмяКоманды = ИмяКнопки;
НоваяКнопка.Заголовок = Текст;
НоваяКнопка.Ширина = 5;
КонецПроцедуры
// ===============================
// Обработчики цифровых кнопок
// ===============================
&НаКлиенте
Процедура Кнопка0(Команда)
ДобавитьСимвол("0");
КонецПроцедуры
&НаКлиенте
Процедура КнопкаДваНуля(Команда)
ДобавитьСимвол("00");
КонецПроцедуры
&НаКлиенте
Процедура Кнопка1(Команда)
ДобавитьСимвол("1");
КонецПроцедуры
&НаКлиенте
Процедура Кнопка2(Команда)
ДобавитьСимвол("2");
КонецПроцедуры
&НаКлиенте
Процедура Кнопка3(Команда)
ДобавитьСимвол("3");
КонецПроцедуры
&НаКлиенте
Процедура Кнопка4(Команда)
ДобавитьСимвол("4");
КонецПроцедуры
&НаКлиенте
Процедура Кнопка5(Команда)
ДобавитьСимвол("5");
КонецПроцедуры
&НаКлиенте
Процедура Кнопка6(Команда)
ДобавитьСимвол("6");
КонецПроцедуры
&НаКлиенте
Процедура Кнопка7(Команда)
ДобавитьСимвол("7");
КонецПроцедуры
&НаКлиенте
Процедура Кнопка8(Команда)
ДобавитьСимвол("8");
КонецПроцедуры
&НаКлиенте
Процедура Кнопка9(Команда)
ДобавитьСимвол("9");
КонецПроцедуры
// ===============================
// Обработчики операций
// ===============================
&НаКлиенте
Процедура КнопкаСложение(Команда)
ДобавитьСимвол("+");
КонецПроцедуры
&НаКлиенте
Процедура КнопкаВычитание(Команда)
ДобавитьСимвол("-");
КонецПроцедуры
&НаКлиенте
Процедура КнопкаУмножение(Команда)
ДобавитьСимвол("*");
КонецПроцедуры
&НаКлиенте
Процедура КнопкаДеление(Команда)
ДобавитьСимвол("/");
КонецПроцедуры
&НаКлиенте
Процедура КнопкаТочка(Команда)
ДобавитьСимвол(".");
КонецПроцедуры
// ===============================
// Обработчики специальных операций
// ===============================
&НаКлиенте
Процедура КнопкаЗнак(Команда)
// Меняем знак числа на противоположный
Попытка
ЭтаФорма.Результат = Строка(-Число(ЭтаФорма.Результат));
Исключение
ЭтаФорма.Результат = "Ошибка";
КонецПопытки;
КонецПроцедуры
&НаКлиенте
Процедура КнопкаПроцент(Команда)
Попытка
ТекущееВыражение = ЭтаФорма.Результат;
// Разбиваем выражение на части
ПозицияОператора = 0;
// Ищем оператор в выражении
Для Индекс = 1 По СтрДлина(ТекущееВыражение) Цикл
Символ = Сред(ТекущееВыражение, Индекс, 1);
Если Найти("+-*/", Символ) > 0 Тогда
ПозицияОператора = Индекс;
Прервать;
КонецЕсли;
КонецЦикла;
// Если нет оператора, просто делим на 100
Если ПозицияОператора = 0 Тогда
ЭтаФорма.Результат = Строка(Число(ТекущееВыражение) / 100);
Возврат;
КонецЕсли;
// Разбираем выражение на части
ПервоеЧисло = Лев(ТекущееВыражение, ПозицияОператора - 1);
Оператор = Сред(ТекущееВыражение, ПозицияОператора, 1);
ВтороеЧисло = Сред(ТекущееВыражение, ПозицияОператора + 1);
// Вычисляем процент от первого числа
ЗначениеПроцента = Число(ПервоеЧисло) * (Число(ВтороеЧисло) / 100);
// Вычисляем итоговое значение
ЭтаФорма.Результат = Строка(Вычислить(ПервоеЧисло + Оператор + Строка(ЗначениеПроцента)));
Исключение
ЭтаФорма.Результат = "Ошибка";
КонецПопытки;
КонецПроцедуры
&НаКлиенте
Процедура КнопкаДробь(Команда)
// Получаем число, обратное текущему (1/х)
Попытка
ЭтаФорма.Результат = Строка(1 / Число(ЭтаФорма.Результат));
Исключение
ЭтаФорма.Результат = "Ошибка";
КонецПопытки;
КонецПроцедуры
&НаКлиенте
Процедура КнопкаОчистить(Команда)
// Очищаем поле результата
ЭтаФорма.Результат = "";
КонецПроцедуры
&НаКлиенте
Процедура КнопкаУдалить(Команда)
// Удаляем последний символ
Если СтрДлина(ЭтаФорма.Результат) > 0 Тогда
ЭтаФорма.Результат = Лев(ЭтаФорма.Результат, СтрДлина(ЭтаФорма.Результат) - 1);
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура КнопкаРавно(Команда)
// Вычисляем результат выражения
Попытка
// Заменяем запятые на точки для корректного вычисления
Выражение = СтрЗаменить(ЭтаФорма.Результат, ",", ".");
// Вычисляем значение и форматируем результат с двумя знаками после запятой
РезультатВычисления = Формат(Вычислить(Выражение), "ЧДЦ=2");
ЭтаФорма.Результат = РезультатВычисления;
Исключение
ЭтаФорма.Результат = "Ошибка";
КонецПопытки;
КонецПроцедуры
// ===============================
// Вспомогательные процедуры
// ===============================
&НаКлиенте
Процедура ДобавитьСимвол(Символ)
// Если предыдущая операция вызвала ошибку, очищаем поле
Если ЭтаФорма.Результат = "Ошибка" Тогда
ЭтаФорма.Результат = "";
КонецЕсли;
// Добавляем символ к текущему значению
ЭтаФорма.Результат = ЭтаФорма.Результат + Символ;
КонецПроцедуры