Статьи 1С программиста

заметки и другая полезная информация по 1С

Создание калькулятора программным способом в 1С

361
04 ноября 2024

В этой статье мы рассмотрим создание калькулятора программным способом в 1С. Для реализации мы будем использовать три основных механизма работы с формой:

1. Реквизиты формы:

- Создание реквизита для хранения результата вычислений через конструктор РеквизитФормы
- Добавление реквизита в форму методом ИзменитьРеквизиты

2. Элементы формы трех типов:

- ПолеФормы - для отображения результата вычислений
- ГруппаФормы - для визуальной организации кнопок калькулятора
- КнопкаФормы - для создания кнопок с цифрами и операциями

3. Команды формы:

- Создание команд для обработки нажатий кнопок через Команды.Добавить
- Привязка команд к кнопкам и создание обработчиков

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

Рассмотрим подробно каждый механизм и его реализацию.

Реквизиты формы являются основой для хранения данных на форме. В нашем случае нам нужен один реквизит для хранения результата вычислений. Важно понимать, что реквизит нужно сначала создать, а затем добавить в форму. После этого к нему можно обращаться через ЭтаФорма:

// 1. Создаем описание типа для реквизита - в нашем случае строка,
//    так как будем хранить как числа, так и операторы
РеквизитРезультат = Новый РеквизитФормы(
    "Результат",                    // Имя реквизита
    Новый ОписаниеТипов("Строка")  // Тип реквизита
);

// 2. Добавляем реквизит в форму
МассивРеквизитов = Новый Массив;
МассивРеквизитов.Добавить(РеквизитРезультат);
ИзменитьРеквизиты(МассивРеквизитов);

// 3. После этого реквизит становится доступен через ЭтаФорма.Результат

Следующим шагом нам необходимо создать элементы формы для отображения данных и взаимодействия с пользователем. Начнем с поля ввода для отображения результата и группы для организации кнопок. Группа позволит нам расположить кнопки в нужном порядке и правильно их выровнять:


// 1. Создаем поле ввода для отображения результата
ПолеРезультат = Элементы.Добавить("ПолеРезультат", Тип("ПолеФормы"));
ПолеРезультат.Вид             = ВидПоляФормы.ПолеВвода;
ПолеРезультат.ПутьКДанным     = "Результат";  // Привязываем к реквизиту
ПолеРезультат.ТолькоПросмотр  = Истина;       // Запрещаем ручной ввод

// 2. Создаем группу для кнопок - все кнопки будут выстроены горизонтально
ГруппаКнопок = Элементы.Добавить("ГруппаКнопок1", Тип("ГруппаФормы"));
ГруппаКнопок.Вид         = ВидГруппыФормы.ОбычнаяГруппа;
ГруппаКнопок.Группировка = ГруппировкаПодчиненныхЭлементовФормы.Горизонтальная;
ГруппаКнопок.Отображение = ОтображениеОбычнойГруппы.Нет;  // Убираем визуальное оформление группы

И наконец, самая важная часть интерфейса - кнопки калькулятора. Для каждой кнопки нам нужно создать команду, которая будет обрабатывать нажатие, создать саму кнопку и связать их между собой. Затем определить процедуру-обработчик, которая будет выполняться при нажатии:


// 1. Создаем команду для кнопки
НоваяКоманда = Команды.Добавить("Кнопка1");
НоваяКоманда.Действие = "Кнопка1"; // Имя процедуры-обработчика

// 2. Создаем кнопку и привязываем к команде
НоваяКнопка = Элементы.Добавить("Кнопка1", Тип("КнопкаФормы"), ГруппаКнопок);
НоваяКнопка.ИмяКоманды = "Кнопка1";
НоваяКнопка.Заголовок = "1";

// 3. Создаем обработчик нажатия
&НаКлиенте
Процедура Кнопка1(Команда)
    // При нажатии добавляем цифру 1 к строке результата
    ЭтаФорма.Результат = ЭтаФорма.Результат + "1";
КонецПроцедуры

Скачать файл

Калькулятор программно:
.epf 8.31 КБ

Полный код решения:

&НаСервере
Процедура ПриСозданииНаСервере(Отказ)
    // Устанавливаем заголовок формы
    ЭтаФорма.АвтоЗаголовок = Ложь;
    ЭтаФорма.Заголовок = "Калькулятор програмно";

    // ===============================
    // Создание реквизита для хранения результата вычислений
    // ===============================
    РеквизитРезультат = Новый РеквизитФормы("Результат", Новый ОписаниеТипов("Строка"));
    МассивРеквизитов = Новый Массив;
    МассивРеквизитов.Добавить(РеквизитРезультат);
    ИзменитьРеквизиты(МассивРеквизитов);

    // ===============================
    // Создание поля для отображения результата
    // ===============================
    ПолеРезультат = Элементы.Добавить("ПолеРезультат", Тип("ПолеФормы"));
    ПолеРезультат.Вид = ВидПоляФормы.ПолеВвода;
    ПолеРезультат.ПутьКДанным = "Результат";  // Привязываем к реквизиту
    ПолеРезультат.ТолькоПросмотр = Истина;    // Запрещаем ручной ввод
    ПолеРезультат.Ширина = 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");
        ЭтаФорма.Результат = РезультатВычисления;
    Исключение
        ЭтаФорма.Результат = "Ошибка";
    КонецПопытки;
КонецПроцедуры

// ===============================
// Вспомогательные процедуры
// ===============================
&НаКлиенте
Процедура ДобавитьСимвол(Символ)
    // Если предыдущая операция вызвала ошибку, очищаем поле
    Если ЭтаФорма.Результат = "Ошибка" Тогда
        ЭтаФорма.Результат = "";
    КонецЕсли;
    // Добавляем символ к текущему значению
    ЭтаФорма.Результат = ЭтаФорма.Результат + Символ;
КонецПроцедуры

361
04 ноября 2024