При работе с зарубежными партнерами, в частности из Китая, программисты часто сталкиваются с необходимостью вывода на печать документов, содержащих китайские иероглифы. В современных версиях платформы 1С:Предприятие (8.x) эта задача решается тривиально благодаря встроенной поддержке Юникода (Unicode). Однако в устаревшей, но все еще активно используемой версии 1С 7.7 поддержка Юникода отсутствует на уровне ядра системы.
Попытка напрямую вставить китайские символы в макет таблицы (.mxl) или передать их в текстовый реквизит приведет к тому, что платформа автоматически преобразует их в знаки вопроса (?). В этой статье мы подробно разберем, как обойти это ограничение платформы 1С 7.7 и успешно сформировать печатные формы с китайскими иероглифами.
Платформа 1С 7.7 была разработана в эпоху господства однобайтовых кодировок (ANSI). Вся текстовая информация в ней обрабатывается в рамках системной кодовой страницы Windows (для русскоязычных систем это обычно Windows-1251). Китайские иероглифы требуют двухбайтового представления (кодировки UTF-8, UTF-16 или национальная китайская кодировка GB18030). Так как платформа отбрасывает «лишние» байты или пытается интерпретировать их по таблице Windows-1251, на выходе получается нечитаемый набор символов или знаки вопроса.
Тем не менее решение этой проблемы существует. Мы проанализируем пять практических методов — от простейшего (с использованием картинок) до профессиональных решений на основе динамической генерации HTML и OLE-автоматизации MS Excel.
---
Если текст на китайском языке является постоянным (например, статичные заголовки таблиц, названия полей «Адрес», «Получатель», «Итого» или условия договора), самым быстрым решением будет использование графических файлов.
Рассмотрим по шагам, как это сделать:
.bmp или .png с высоким разрешением..mxl).Преимущества: Простота реализации, не требующая написания сложного программного кода.
Недостатки: Текст из картинок не всегда красиво печатается на физических принтерах из-за сжатия графики платформой 1С 7.7. На печати края символов могут выглядеть размытыми или пикселизированными. Метод абсолютно непригоден для динамических данных (таких как наименования товаров, адреса конкретных контрагентов или имена лиц).
---
Для реализации качественной печати динамических данных без потери четкости шрифтов целесообразно переложить задачу вывода информации на внешние приложения, изначально работающие с Юникодом (MS Excel или MS Word).
Выясним схему работы данного механизма:
Template.xlt в Excel), в котором все постоянные надписи (включая китайские иероглифы) уже внесены в ячейки стандартными средствами Excel.Проанализируем пример кода на языке 1С 7.7 для заполнения такого шаблона:
// Создание объекта связи с Excel
Попытка
Эксель = СоздатьОбъект("Excel.Application");
Исключение
Предупреждение("На компьютере не установлен Microsoft Excel!");
Возврат;
КонецПопытки;
// Открытие файла шаблона, где уже есть китайский текст
ПутьКШаблону = КаталогИБ() + "Templates\Invoice_CN.xlt";
РабочаяКнига = Эксель.Workbooks.Add(ПутьКШаблону);
Лист = РабочаяКнига.Worksheets(1);
// Заполнение динамических реквизитов из 1С
Лист.Cells(5, 3).Value = СокрЛП(Документ.НомерДок);
Лист.Cells(5, 4).Value = Формат(Документ.ДатаДок, "Д ДДММГГГГ");
Лист.Cells(10, 2).Value = Число(Документ.Итог("Сумма"));
// Делаем Excel видимым для пользователя
Эксель.Visible = 1;
При таком подходе китайский текст, сохраненный в самом шаблоне xls, не подвергается искажению со стороны 1С и выводится на печать в идеальном векторном качестве.
---
Что делать, если китайский текст должен быть динамическим (например, наименования номенклатуры на китайском языке хранятся в базе данных)? Передать напрямую строку с иероглифами из 1С в Excel по OLE не удастся. Однако мы можем передать коды этих символов, а в самом Excel преобразовать их обратно в иероглифы с помощью макроса VBA.
Разберем этот изящный способ по шагам:
Шаг 1. Кодирование в 1С. В базе данных 1С (в справочнике Номенклатуры) китайские наименования сохраняются в обычном текстовом реквизите в виде строки числовых кодов символов Юникода, разделенных точкой с запятой. Например, иероглиф "瓜" (код 12160) запишется как строка "12160;". Для удобства ввода таких кодов можно использовать внешние конвертеры.
Шаг 2. Передача данных и запуск макроса. Из 1С мы выгружаем эту кодовую строку в ячейку Excel, а затем программно вызываем VBA-макрос, сохраненный в шаблоне Excel, который декодирует числовые коды в реальные символы с помощью встроенной функции ChrW().
Посмотрим на пример VBA-кода, который должен содержаться в шаблоне Excel:
Sub ConvertCodesToUnicode()
Dim cell As Range
Dim parts() As String
Dim result As String
Dim i As Integer
' Проходим по всем заполненным ячейкам листа
For Each cell In ActiveSheet.UsedRange
' Если ячейка содержит закодированную строку (признак - точка с запятой)
If InStr(cell.Value, ";") > 0 Then
parts = Split(cell.Value, ";")
result = ""
For i = LBound(parts) To UBound(parts)
If IsNumeric(parts(i)) Then
' Преобразование кода в Юникод-символ
result = result & ChrW(CInt(parts(i)))
End If
Next i
cell.Value = result
End If
Next cell
End Sub
Управляющий код в 1С 7.7, который передает данные и запускает этот макрос, выглядит следующим образом:
// Передаем строку кодов иероглифов в Excel
Лист.Cells(12, 2).Value = "12160;12161;12162;"; // Пример кодов китайских символов
// Запускаем макрос конвертации, внедренный в шаблон
Эксель.Run("ConvertCodesToUnicode");
---
Если вам требуется не только выводить иероглифы на печать, но и отображать их пользователю на форме справочника или документа в 1С 7.7, стандартные поля ввода использовать нельзя. Вместо них на форму помещается объект ActiveX Internet Explorer (WebBrowser).
Для реализации этого метода:
命. Элемент ActiveX корректно отобразит иероглифы на экране, а при сохранении передаст числовые коды обратно в модуль 1С для записи в базу данных.---
Для получения идеально четких шрифтов при печати без использования пакета MS Office можно применить генерацию отчета в формате HTML с последующей отправкой на принтер средствами операционной системы.
Выясним, как это работает программно:
.html.<table>, <tr>, <td>, а китайский текст выводится в виде HTML-кодов символов (например, 万).Рассмотрим детальный пример реализации этого метода:
// Создание текстового файла для HTML-отчета
ФайлHTML = СоздатьОбъект("Текст");
ФайлHTML.ДобавитьСтроку("<!DOCTYPE html>");
ФайлHTML.ДобавитьСтроку("<html>");
ФайлHTML.ДобавитьСтроку("<head>");
ФайлHTML.ДобавитьСтроку("<meta http-equiv=""Content-Type"" content=""text/html; charset=utf-8"">");
ФайлHTML.ДобавитьСтроку("<style>");
ФайлHTML.ДобавитьСтроку("body { font-family: 'SimSun', 'Arial', sans-serif; }");
ФайлHTML.ДобавитьСтроку("table { border-collapse: collapse; width: 100%; }");
ФайлHTML.ДобавитьСтроку("td { border: 1px solid black; padding: 5px; }");
ФайлHTML.ДобавитьСтроку("</style>");
ФайлHTML.ДобавитьСтроку("</head>");
ФайлHTML.ДобавитьСтроку("<body>");
// Добавление таблицы с русским и китайским текстом
ФайлHTML.ДобавитьСтроку("<table>");
ФайлHTML.ДобавитьСтроку("<tr>");
ФайлHTML.ДобавитьСтроку("<td>Наименование товара (RU)</td>");
ФайлHTML.ДобавитьСтроку("<td>Наименование товара (CN)</td>");
ФайлHTML.ДобавитьСтроку("</tr>");
ФайлHTML.ДобавитьСтроку("<tr>");
ФайлHTML.ДобавитьСтроку("<td>Кабель медный</td>");
// Вывод китайских иероглифов через их десятичные коды Unicode
ФайлHTML.ДобавитьСтроку("<td>Ž铜缆管</td>");
ФайлHTML.ДобавитьСтроку("</tr>");
ФайлHTML.ДобавитьСтроку("</table>");
ФайлHTML.ДобавитьСтроку("</body>");
ФайлHTML.ДобавитьСтроку("</html>");
// Запись файла на диск во временный каталог
ИмяФайла = КаталогВременныхФайлов() + "cn_report.html";
ФайлHTML.Записать(ИмяФайла);
// Вывод на принтер через COM-объект Internet Explorer
Попытка
Браузер = СоздатьОбъект("InternetExplorer.Application");
Браузер.Navigate(ИмяФайла);
// Ожидаем завершения загрузки документа в память браузера
Пока Браузер.ReadyState <> 4 Цикл
// Приостановка для ожидания
ВвестиСтроку("", "", 1, 0, 1);
КонецЦикла;
// Делаем браузер видимым, если нужно показать предварительный просмотр
// Браузер.Visible = 1;
// Вызов системного диалога печати без отображения самого браузера
// Параметр 6 означает команду OLECMDID_PRINT, параметр 2 - OLECMDEXECOPT_DONTPROMPTUSER (печать без вопросов)
Браузер.ExecWB(6, 2);
Исключение
Сообщить("Ошибка печати: " + ОписаниеОшибки(), "!");
КонецПопытки;
Преимущества метода: Высочайшая скорость работы, отсутствие требований к наличию установленного MS Office на компьютере пользователя, идеальное качество векторного шрифта при печати благодаря тому, что операционная система Windows сама подтягивает необходимые шрифты (например, SimSun) для отрисовки иероглифов.
---
Выбор конкретного метода зависит от архитектуры вашей базы данных и динамичности выводимой информации: