При автоматизации обмена данными между 1С и Microsoft Excel программисты часто сталкиваются с необходимостью программного определения имени столбца. Если в COM-объектах или при чтении файлов нам известен порядковый номер колонки (например, 30), то для формирования формул или обращения к диапазонам часто требуется буквенное представление (например, "AD"). В этой статье мы подробно разберем, как реализовать алгоритмы прямого и обратного преобразования, а также рассмотрим альтернативные способы с использованием возможностей самого Excel.
Прежде чем переходить к коду, проанализируем математическую суть задачи. Система именования столбцов в Excel — это так называемая биективная двадцатишестеричная система счисления. Ее главное отличие от стандартных систем (например, десятичной или шестнадцатеричной) заключается в отсутствии символа «ноль».
Посмотрим на пример: после колонки "Z" (номер 26) идет "AA" (номер 27). Если бы это была обычная 26-ричная система, то "A" должна была бы означать "0", но здесь "A" — это "1". Именно поэтому стандартные функции перевода систем счисления из школьного курса информатики требуют небольшой модификации — вычитания единицы на каждом шаге цикла. Это позволяет корректно сопоставлять остатки от деления буквам латинского алфавита (от A до Z).
Рассмотрим реализацию функции на встроенном языке 1С. Этот метод является универсальным и работает максимально быстро, так как не требует запуска внешних приложений.
Разберем по шагам алгоритм функции ВСтолбецЭкселя:
Номер столбца.Пока, пока число больше нуля, мы вычисляем остаток от деления (с учетом смещения на единицу).Симв() и ASCII-код символа "A" (код 65), чтобы получить нужную букву.
Функция ВСтолбецЭкселя(Знач Номер)
Перем А, Результат;
А = Номер;
Результат = "";
Пока А > 0 Цикл
// Вычитаем 1 для компенсации отсутствия нуля в системе Excel
Результат = Симв(((А - 1) % 26) + 65) + Результат;
А = Цел((А - 1) / 26);
КонецЦикла;
Возврат Результат;
КонецФункции
Проанализируем пример: если мы передадим в функцию число 30, на первой итерации (30-1)%26 даст 3. Код 65 + 3 = 68 соответствует букве "D". Далее (30-1)/26 даст 1. На второй итерации (1-1)%26 даст 0. Код 65 + 0 = 65 соответствует букве "A". Итог: "AD".
Теперь разберем обратную задачу: нам дана строка "AD", и мы хотим получить число 30. Этот алгоритм работает по принципу накопления разрядов при движении по строке слева направо.
Выясним логику вычислений:
Функция ИзСтолбцаЭкселя(Знач ИмяСтолбца)
Перем Результат, дл, и, КодСимвола;
ИмяСтолбца = ВРег(СокрЛП(ИмяСтолбца));
Результат = 0;
дл = СтрДлина(ИмяСтолбца);
Для и = 1 По дл Цикл
КодСимвола = КодСимв(Сред(ИмяСтолбца, и, 1));
// Получаем значение буквы (A=1, B=2...)
Результат = Результат * 26 + (КодСимвола - 64);
КонецЦикла;
Возврат Результат;
КонецФункции
Если в вашем модуле 1С уже создано COM-соединение с Excel (объект Excel.Application), мы можем не писать свои функции, а делегировать эту задачу самому приложению. Это гарантирует 100% совместимость с логикой Microsoft, даже если в будущем правила изменятся.
Посмотрим на пример получения буквенного адреса через объект Cells:
// Предположим, ЭксельОбъект уже создан
// Получаем адрес ячейки в формате R1C1 или A1
НомерСтолбца = 30;
Ячейка = ЭксельОбъект.Cells(1, НомерСтолбца);
// Address(0, 0) вернет относительный адрес без знаков $, например "AD1"
ПолныйАдрес = Ячейка.Address(0, 0);
// Чтобы оставить только буквы, удалим номер строки (в данном случае "1")
БуквыСтолбца = СтрЗаменить(ПолныйАдрес, "1", "");
Для обратного преобразования (из букв в число) достаточно обратиться к свойству Column объекта Range:
// Передаем буквенное имя, получаем номер
ИмяСтолбца = "AD";
НомерСтолбца = ЭксельОбъект.Range(ИмяСтолбца + "1").Column;
// Результат будет равен 30
При реализации подобных механизмов важно помнить о лимитах разных версий Excel, чтобы ваша обработка не вызвала критическую ошибку при работе с большими объемами данных:
IV.XFD.Если вам требуется обрабатывать огромное количество ячеек в цикле, использование COM-объектов может замедлить работу системы. В таких случаях мы рекомендуем использовать Метод 1 (алгоритмический), так как он выполняется внутри движка 1С и не требует межпрограммного взаимодействия. Для дополнительного ускорения в 1С 7.7 можно заранее подготовить строку-алфавит и обращаться к ней через Сред(), что избавит от лишних вычислений кодов ASCII.
Таким образом, мы рассмотрели все основные способы "растягивания" и конвертации столбцов. Выбор конкретного метода зависит от версии платформы 1С и интенсивности использования операций преобразования в вашем коде.