Excel и Access тоже могут печатать на матричном принтере

Как Вы и ожидали после моей предыдущей статьи ("Как Visual FoxPro печатает..."), в данной статье будет освещен процесс печати данных из приложений Microsoft Office (примеры в Excel и Access). Повторюсь, что особенностью публикации является рассмотрение вывода на матричный принтер в текстовом режиме. Как уже упоминалось в предыдущей статье, существует масса документов, для которых не требуется высокое качество, достижимое на современных лазерных или струйных принтерах, например, квитанции, абонентские счета, расчетные листки по зарплате и пр.

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

Данный процесс требует некоторых навыков программирования на Visual Basic for Applications, встроенном в MS Office, но будьте уверены - практический результат оправдает все Ваши усилия.

Как уже было описано в предыдущей статье, основная идея состоит в следующем - программируем вывод в виде текстового файла, а затем с помощью .BAT-файла (который запускается в сессии DOS) копируем текстовый файл на принтер.

Для этого необходимо дополнительно настроить принтер. Зайдите в меню кнопки "Пуск / Настройка / Принтеры" и щелкните правой кнопкой по значку матричного принтера. Зайдите в "Свойства" и откройте закладку "Сведения". Нажмите "Параметры порта" и в появившемся окне отметьте галочкой пункт "Очередь для заданий печати DOS".

Создайте .BAT-файл (например, MATRIX.BAT в каталоге "Мои документы") и впишите в него единственную строку:

COPY %1 TO PRN

Она дает команду операционной системе копировать файл, указанный в параметре на устройство PRN, т.е. на принтер. Вообще-то, имя PRN - синоним имени LPT1, которые оба указывают на один и тот же порт принтера. Если же у Вас матричный принтер подключен к другому порту либо он сетевой, то лучше сразу указать имя порта.

Потом в корневом каталоге на диске С: создайте файл-ярлык MATRIX.PIF, указывающий на MATRIX.BAT, откройте его свойства и на закладке "Программа" включите параметр "Закрывать окно по завершении сеанса работы", а на закладке "Разное" пункт "Фоновый режим / Полная остановка" обязательно выключите.

Сначала рассмотрим адаптацию существующей таблицы Excel. Для этого нам понадобятся панели "Visual Basic" и "Элементы управления". Установите их через меню "Вид / Панели инструментов". Далее найдите на них кнопку "Редактор Visual Basic" - запустится вышеназванный редактор макросов.

Создайте новый модуль и впишите в него следующую строку:

PUBLIC DECLARE FUNCTION WinExec LIB "Kernel32" (BYVAL FName AS STRING, BYVAL WinSize AS LONG) AS LONG

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

Так как мы собираемся копировать текст на принтер из сессии DOS, то нам понадобится конвертировать строки русских символов из кодовой таблицы Windows-1251 в DOS-866.

Такой функции в файле справки я не нашел, поэтому пришлось описывать свою:

PUBLIC FUNCTION WinToDOS(Line AS STRING) AS STRING

Ее полный исходный текст приводить здесь бессмысленно, загляните на сайт и скачайте рабочий пример со всеми исходниками. Если же горите желанием поскорее попробовать, то используйте английский текст - его перекодировать не нужно. Кроме того, функция перекодировки строк на Visual Basic будет немного замедлять работу программы при выводе больших документов, поэтому если у Вас есть .DLL-библиотека с такой функцией, воспользуйтесь оператором DECLARE, как в предыдущем примере, и подключите ее к Вашему проекту - будет быстрее.

Теперь переключитесь назад в Excel и в своей книге создайте кнопку. Нажмите на панели "Элементы управления" кнопку с простой подписью - "Кнопка". Теперь на самой таблице один раз щелкните левой кнопкой мыши - появится настоящая кнопка. Щелкните по ней уже правой кнопкой мыши и в появившемся меню выберите пункт "Исходный текст". Автоматически активизируется редактор Visual Basic и откроет окно с шаблоном процедуры для ввода исходного текста макроса.

Введите следующие строки: Private Sub CommandButton1_Click()

'Описание переменных
Dim Line As String, Res As Long

'Открытие потока вывода в текстовый файл
Open "C:\Output.txt" For Output Shared As #1

'Перенос данных таблицы в переменную
Line = Range("A1").Value + Str(Range("B1").Value)

'Запись строки в файл
'с одновременной перекодировкой
Write #1, WinToDOS(Line)

'Строка запуска программы
Line = "C:\Matrix.PIF C:\Output.txt" + Chr(0)
Write #1, Line

'Закрытие потока
Close #1

'Запуск .PIF-файла с параметром -
'имя файла в командной строке
Res = WinExec(Line, 7)

'Отображение результатов запуска
Range("B2").Value = Res
Select Case Res
Case 0
Range("C2").Value = "The system is out of memory or resources"
Case 1
Range("C2").Value = "The.EXE file is invalid (non-Win32.EXE or error in.EXE image)"
Case 2
Range("C2").Value = "The specified file was not found"
Case 3
Range("C2").Value = "The specified path was not found"
Case Is> 31
Range("C2").Value = "Successfully executed!"
End Select

'Конец подпрограммы
End Sub

Снова переключитесь в Excel. Как видно из текста программы, в ячейку A1 надо записать какой-нибудь текст, а в B1 — любое число. Эти данные и будут отпечатаны. Далее, на панели "Элементы управления" найдите нажатую кнопку "Режим конструктора" и нажмите ее, чтобы она пришла в нормальное состояние — режим конструктора будет отключен.
А вот теперь смело нажимайте на созданную Вами большую кнопку на таблице и наслаждайтесь чувством превосходства.
Важно! При открытии этой книги в последующем будет появляться грозное предупреждение от Microsoft — будьте осторожны, мол там могут быть вирусы, и если Вы доверяете источнику, откуда к Вам этот файл попал, тогда открывайте. Думаю, что Вы сами себе вирусы не напишете, а я этим делом не занимаюсь, поэтому открывайте смело, но не отключайте макросы, иначе команды работать не будут.
Этот пример в ZIP-архиве, конечно, можно взять на сайте www.victoryday.web.com в разделе Programming. В том же архиве находится и файл примера для Access. Однако новичкам он будет мало полезен, т.к. в отличие от Excel его сложнее будет адаптировать к существующим приложениям — для вывода в текстовый файл информацию нужно брать из множества таблиц и переменных.
Но более опытным программистам это не составит особого труда. А что касается остального кода процедур, то его можно перенести практически без изменений — начиная с 97-ой версии Office, язык VBA одинаков для всех приложений.
Но есть одна деталь — для новичков. В Access подпрограммы на Visual Basic называются не макросами, как в других приложениях Office, а программами, которые хранятся в модулях. А его макросы — это немного из другой оперы, мы их трогать не будем.
Рассмотрим все операции подробнее.
Откройте любую базу данных или создайте новую.
Откройте закладку "Модули" и создайте новый модуль. В нем введите описание нужных нам вспомогательных функций — запуска внешних программ и перекодировки строк, т.е. все как в модуле в Excel.
Далее, откройте закладку "Формы" и создайте новую форму. В ней аналогично, как в Excel, создайте кнопку и щелкните по ней правой кнопкой мыши. Во всплывающем меню выберите пункт "Свойства". В окне свойств откройте закладку "События", выберите событие "Нажатие кнопки", и справа появится кнопочка с многоточием. Нажимайте ее — и откроется окно для редактирования подпрограммы обработки данного события.
Введите туда следующий код:

Private Sub Кнопка0_Click()

'Описание переменных
Dim Line As String, Res As Long, Info As String, Ok As Integer

'Открыть поток вывода в текстовый файл
Open "C:\Output.txt" For Output Shared As #1

Line = "Hello, world!!! Привет, друзья;-)"

'Запись строки в файл
'с одновременной перекодировкой
Write #1, WinToDOS(Line)

'Строка запуска процесса печати
Line = "c:\matrix.pif c:\output.txt" + Chr(0)
Write #1, Line

'Закрытие потока
Close #1

'Отображение результатов запуска
Res = WinExec(Line, 7)
Select Case Res
Case 0
Info = "The system is out of memory or resources"
Case 1
Info = "The.EXE file is invalid (non-Win32.EXE or error in.EXE image)"
Case 2
Info = "The specified file was not found"
Case 3
Info = "The specified path was not found"
Case Is> 31
Info = "Successfully executed!"
End Select
Ok = MsgBox(Str(Res) + " " + Info, vbOKOnly + vbInformation, "Сообщение системы")

'Конец подпрограммы
End Sub

Сохраните форму, закройте и потом нажмите "Открыть" — запуститься Ваша форма, и уже можно нажимать кнопку вызова подпрограммы печати.
Так же, как и было описано в предыдущей статье по Visual FoxPro, в профессиональных приложениях нежелательно использовать жестко прописанные имена файлов вывода. Они даны в этих примерах, чтобы не загромождать основной алгоритм, иначе за деревьями можно и леса не увидеть. Для этих целей лучше использовать временные файлы. Но, к сожалению, в Офисной справке по Visual Basic я не нашел функций, аналогичных как в Visual FoxPro. Но это не беда — можно написать самостоятельно. Используйте для этого фунцию генерации случайных чисел.
Например, выражение STR(INT(RANDOM()* 100000000) вернет строку, состоящую из цифр, которую можно использовать для создания временного файла. Добавьте к нему любое расширение типа .~0TMP и смело создавайте файл.
Но тут есть одна ма-а-ленькая деталь — их нужно когда-нибудь удалять. В программе удалять файл сразу же после отправки на печать не получится.
Windows — это многозадачная система;-), поэтому копирование файла на принтер будет происходить одновременно с продолжением выполнения Вашей программы. Т.е. программа попытается удалить файл, который заблокирован программой копирования — возникнет ошибка. Тут можно пойти двумя путями:
1. В используемом .BAT-файле второй строкой допишите команду удаления:

DEL %1

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

DEL *.~0TMP

Затем при завершении приложения запустите его ранее описанным способом, и все в порядке.
В обеих статьях рассмотрен лишь базовый принцип вывода на матричный принтер. Такие особенности вывода, как применение управляющих кодов, — это уже другая тема. Полностью описание управляющих кодов обычно приведено в руководстве по эксплуатации принтера, по крайней мере так было у всех моделей Epson. В свои студенческие годы я написал специальную DOS-утилиту для печати текстов всеми возможными аппаратными шрифтами. Ее вместе с исходными текстами можно свободно скачать с www.victoryday.web.com из раздела OpenSoft.
Своими статьями по FoxPro и Basic я хочу показать любителям сравнивать языки программирования — каждая среда разработки по-своему удобна. Выбирать то или иное средство нужно в зависимости от поставленной задачи — как удобнее и проще ее решить.
И в этом плане вышеупомянутые средства занимают почетное место наряду с модными Delphi, C++ и Java. А офисное программирование вообще позволяет большую часть работы сделать средствами Office, применяя Visual Basic лишь для специфических целей. Если хотите еще более убедительные аргументы — заглядывайте почаще на сайт или пишите на vic_mak@newmail.net.
Ну, а по поводу применения в макросах Visual Basic оператора DECLARE для описания внешних процедур хочется сделать лирическое отступление.
НЕ ИСПОЛЬЗУЙТЕ ЭТУ ВОЗМОЖНОСТЬ ДЛЯ НАПИСАНИЯ ВИРУСОВ! Лучше напишите что-нибудь полезное для других, скорее всего за это Вам еще и заплатят (не забудьте поделиться за идею;-) и скажут спасибо. А за вирусы не только никто не заплатит, но можете и проблем заиметь. Так что займитесь делом и будьте здоровы.

Виктор Маковчик


Компьютерная газета. Статья была опубликована в номере 23 за 2000 год в рубрике программирование :: разное

©1997-2024 Компьютерная газета