Как вывести ровную таблицу умножения в 1С с помощью циклов?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

Алгоритмы построения таблицы: от простого к сложному

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

Вариант 1: Вложенные циклы

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


Для Множитель1 = 1 По 9 Цикл
    СтрокаТаблицы = "";
    Для Множитель2 = 1 По 9 Цикл
        СтрокаТаблицы = СтрокаТаблицы + " " + Множитель1 + "*" + Множитель2 + "=" + Множитель1 * Множитель2;
    КонецЦикла;
    Сообщить(СтрокаТаблицы);
КонецЦикла;

В этом примере мы накапливаем результат умножения в переменную СтрокаТаблицы внутри второго цикла, а затем выводим сформированную строку с помощью метода Сообщить().

Вариант 2: Использование одного цикла

Если стоит строгая задача уместить логику в один цикл, мы можем воспользоваться математическими операциями получения целой части от деления и остатка от деления. Проанализируем следующий подход, где мы итерируемся от 0 до 99:


СтрокаТаблицы = "";
Для Индекс = 0 По 99 Цикл
    Множитель1 = Цел(Индекс / 10);
    Множитель2 = Индекс % 10;
    СтрокаТаблицы = СтрокаТаблицы + " " + Множитель1 + "*" + Множитель2 + "=" + Множитель1 * Множитель2;
    
    Если Множитель2 = 9 Тогда
        Сообщить(СтрокаТаблицы);
        СтрокаТаблицы = "";
    КонецЕсли;
КонецЦикла;

Функция Цел() возвращает нам десятки (первый множитель), а операция % (остаток от деления) возвращает единицы (второй множитель). Как только второй множитель достигает 9, мы выводим строку и очищаем буфер.

Почему таблица получается кривой и как это исправить?

С алгоритмами циклов мы разобрались, но если мы запустим этот код, колонки не будут выровнены. Разберем истинную причину этого явления.

Окно служебных сообщений 1С по умолчанию использует пропорциональный шрифт (например, Tahoma или Segoe UI). В таких шрифтах ширина символов различается. Цифра «1» визуально у́же, чем цифра «8», а стандартный пробел значительно у́же любой цифры. Следовательно, когда мы пытаемся скомпенсировать недостающий разряд в однозначном числе с помощью обычного пробела, ширина строки все равно не совпадает с шириной строки с двузначным числом. Таблица неизбежно «едет».

Как мы можем это решить? Рассмотрим несколько подходов к форматированию строк.

  1. Заполнение нулями. Если вместо пробелов выводить цифру "0" (например, писать "01" вместо " 1"), ширина символов выровняется, и таблица станет ровнее. В 1С для этого отлично подходит функция Формат(). Применив форматную строку Формат(Результат, "ЧЦ=2; ЧВН="), мы автоматически дополним числа ведущими нулями.
  2. Использование специального Unicode-символа. Если нули режут глаз, можно использовать специальный неразрывный пробел из таблицы Юникода, который по ширине равен цифре («Математическая моноширинная цифра»). В 1С его можно получить с помощью функции Символ(8199).
  3. Функция СтрДополнить(). Эта функция позволяет автоматически дополнить строку до нужной длины заданным символом слева или справа, что делает код более читаемым, избавляя от сложных конструкций с проверкой длины строки.

Проанализируем более сложный пример вывода с использованием массивов и шаблонов строк (доступно в новых версиях платформы):


ШаблонУмножения = "%1 х %2 = %3";
Для Число2 = 1 по 10 Цикл
    ДанныеПоСтроке = Новый Массив;
    Для Число1 = 2 по 5 Цикл
        Произведение = Число1 * Число2;
        РезультатЧасть = СтрШаблон(ШаблонУмножения, Число1, Число2, Произведение);
        ДанныеПоСтроке.Добавить(РезультатЧасть);
    КонецЦикла;
    Сообщить(СтрСоединить(ДанныеПоСтроке, " | "));
КонецЦикла;

Архитектурно правильный подход в 1С: Предприятие

Хотя мы можем прибегать к ухищрениям с Юникодом и пробелами, важно понимать принципы платформы. С точки зрения стандартов разработки 1С, метод Сообщить() предназначен для информирования пользователя о ходе выполнения процесса или об ошибках. Вывод структурированных табличных данных в это окно — это методически неверный подход (bad practice).

Для построения таблиц любой сложности в 1С предназначены специальные объекты. Рассмотрим, что лучше использовать вместо сообщений:

1. Объект ТекстовыйДокумент с моноширинным шрифтом

Если вам нужно вывести именно текстовую таблицу, создайте объект ТекстовыйДокумент. Выведите его на форму или покажите в отдельном окне, предварительно установив для него моноширинный шрифт (например, Courier New). В таком шрифте все буквы, цифры и пробелы имеют строго одинаковую ширину. Математическое добавление обычных пробелов для выравнивания колонок в этом случае сработает идеально.

2. Объект ТабличныйДокумент (Идеальное решение)

Это классический инструмент 1С, напоминающий сетку Excel. В объекте ТабличныйДокумент данные помещаются в отдельные ячейки (области макета). При таком подходе проблема выравнивания текста пробелами полностью исчезает. Вы просто задаете ширину колонки и указываете выравнивание текста по правому или левому краю в свойствах самой ячейки.

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

← На главную