Скачиваний:
12
Добавлен:
30.09.2018
Размер:
40.13 Кб
Скачать

Visual Basic с нуля. Глава 13. Работа с принтером. Объект Printer. Его свойства и методы. Функция InStr. Пособие-самоучитель on-line "Visual Basic с нуля" Глава 13. Работа с принтером. Объект Printer. Его свойства и методы. Функция InStr. Скачать исходник программы Printing Дата создания 29.01.2005 {Автор 4us} Ну, друзья мои, мы дошли до 13-й чертовой главы. Не будем суеверными и попробуем разобраться, как вывести на печать результаты нашей программной деятельности. Не хочу тебя огорчать, но для этого нужен принтер, который подключен к твоему компьютеру и готов к работе. Если его нет, эту главу не читай.

Традиционно во всех учебных изданиях разбирается пример, как вывести на печать всю форму целиком. На фига нужно выводить всю форму, какая от этого нам польза, остается для меня загадкой на протяжении долгого времени и гнетет мое сознание. Однако, отдавая дань традициям, все-таки напомню, что форма выводится на печать с помощью метода PrintForm. То бишь, ты берешь любую готовую программу, добавляешь кнопку Command, называешь ее "Печать", и в код ее процедуры гордо пишешь:

Form1.PrintForm

Запускаешь программу, нажимаешь эту созданную кнопку и у тебя на печать выходит Form1 со всеми элементами-объектами, видимыми на момент печати. Ты некоторое время смотришь на это безумие, потом перед командой PrintForm делаешь невидимыми кнопки и в надежде на чудо, снова повторяшь процесс, но чуда не произошло. Кнопок теперь нет, но распечатка красивше от этого не стала. И понося на чем свет VB, Microsoft и его хозяина, выключаешь все и идешь пить пиво.

Вот про печать и все.

Шучу. Во-первых на печать надо выводить именно то, что мы хотим, а не то, что можем и в полном объеме. Во-вторых, расположение объектов на форме может быть красиво, но на листе дизайн должен быть совсем иной и объекты расположены по-другому, а форма для создания печатного документа вообще не годится.

А теперь скажу, что подготовка для печати красивой страницы - достаточно кропотливый процесс. То есть, надо программно расчитывать месторасположение всех элементов страницы, причем в зависимости от формата листа и размера шрифта и всего остального. Зато тщательно подготовленная страница выглядит, как настоящий документ, очень достойно.

Основной объект, с которым мы будем работать - Printer. Несмотря на то, что это объект, ни самого объекта в окне инструментов или на форме, ни свойств в окне свойств мы не увидим. Все надо делать программно. Но этот объект имеет просто кучу свойств и методов, большинство из которых нам нужны. Постараемся разобраться подробнее. Хочу заметить, что не все принтеры поддерживают все свойства объекта Printer. В этом случае разные свойства могут вызывать одинаковое действие или же вообще вызывать ошибку. Я для написания примера использовал довольно-таки старый лазерный черно-белый принтер HP LaserJet 5L, и основываясь на его возможностях и готовил пример. Можно было взять цветной струйник, но струйники - дороги в эксплаутации и, как правило, документы печатаются на лазерных принтерах.

Итак, начнем со свойств, список важнейших из них приведен в таблице ниже:

Свойство Характеристика Синтаксис .Copies определяет число печатаемых копий Printer.Copies=1 (одна копия) .ColorMode определяет цветную или монохромную (оттенки серого) печать vbPRCMMonochrome=1 (черно-белая) vbPRCMColor =2 (цветная). Монохромные принтеры это свойство игнорируют. Printer.ColorMode=1 или

Printer.ColorMode=vbPRCMMonochrome .CurrentX и .CurrentY устанавливают горизонтальную (CurrentX) или вертикальную (CurrentY) координаты для начала (продолжения) печати. Определяется по-умолчанию в твипах, либо в текущих единицах измерения Printer.CurrentX=500

Printer.CurrentY=1000 .Duplex возвращает или устанавливает значение, которое определяет, будет ли страница печататься с двух сторон, константы: vbPRDPSimplex =1, vbPRDPHorizontal= 2, vbPRDPVertical=3. Printer.Duplex=1 (Одностороння печать с текущей ориентацией листа)

Printer.Duplex=2 (Двухсторонняя печать горизонтальной страницы)

Printer.Duplex=3 (Двухсторонняя печать вертикальной страницы)

.Font определяет "жирность" текста, подчеркивание, перечеркивание, курсив и т.п. Printer.Font.Bold = True (жирный)

Printer.Font.Underline = True (подчеркивание) .FontCount возвращает число доступных шрифтов Text1.Text=Printer.FontCount .FontName возвращает или устанавливает имя шрифта Printer.FontName="Arial" (устанавливает шрифт Arial) .Fonts возвращает имена всех доступных шрифтов Dim I As Long

For I = 0 To Printer.FontCount -1

List1.AddItem Printer.Fonts (I)

Next I .FontSize возвращает или устанавливает размер шрифта в пунктах (максимальное значение 2160). Задается после задания свойства FontName. При использовании шрифтов TrueType менее 8 пунктов, надо сначала задать свойство FontSize, затем FontName, а потом снова FontSize Printer.FontSize=18 .Height и

.Width устанавливают физические размеры листа бумаги. Используются вместо установок PiperSize. Для Printer задается только в твипах. Printer.Height=5000 (Высота)

Printer.Widtht=3000 (Ширина) .Orientation возвращает или устанавливает значение, указывающее, в вертикальном или горизонтальном расположении печатаются документы. Принимает значение двух констант: vbPRORPortrait =1 (вертикаль), vbPRORLandscape=2 (горизонт) Printer.Orientation=1 или

Printer.Orientation=vbPRORPortrait .Page возвращает текущий номер страницы, начиная с единицы и шагом единица Printer.Print Printer.Page (вывод на печать текущей страницы) .PaperBin возвращает или устанавливает значение, указывающее для принтера установленный по умолчанию лоток для подачи бумаги. Константы перечислены в библиотеке объектов Visual Basic (VB) в Object Browser. Printer.PaperBin=1 (верхний лоток)

Printer.PaperBin=2 (нижний лоток)

Printer.PaperBin=3 (средний лоток)

Printer.PaperBin=4 (ручная подача)

Printer.PaperBin=7 (лоток по умолчанию)

и т.д.

.PaperSize возвращает или устанавливает значение, указывающее размер бумаги для текущего принтера.

vbPRPSA4= 9 для листа A4, 210 x 297 мм

vbPRPSUser=256 для пользовательского

Константы перечислены в библиотеке объектов Visual Basic (VB) в Object Browser.

Printer.PaperSize=9 или

Printer.PaperSize=vbPRPSA4

(установка листа A4) .PrintQuality возвращает или устанавливает значение, указывающее разрешающую способность принтера (отрицательная константа).

Можно также задавать положительные значения в точках на дюйм (dpi). Printer.PrintQuality=-1 (черновой- draft)

Printer.PrintQuality=-2 (низкая- Low)

Printer.PrintQuality=-3 (средняя- Medium)

Printer.PrintQuality=-4 (высокая- High)

Printer.PrintQuality=300 (разрешение 300 dpi) .Zoom возвращает или устанавливает процентное соотношение, по которому увеличивается или уменьшается масштаб вывода на печать. Число обозначает процент и по умолчанию равно 0, что соответствует стандартному размеру. Printer.Zoom=50 (лист с уменьшением 1:2) Теперь, как ни печально, надо переходить к методам, но их не так много. На мой взгляд важные приведены в таблице ниже:

Метод Характеристика Синтаксис .EndDoc завершает формирование листа для печати и начинает печать Printer.EndDoc .KillDoc немедленно завершает печать сформированной страницы Printer.KillDoc .NewPage завершает текущую страницу на объекте Printer и переходит на следующую Printer.NewPage .TextHeight и .TextWidth возвращают высоту (TextHeight ) и длину (TextWidth) текстовой строки, которая получится при ее выводе на печать или на форму с использованием текущего шрифта. В возвращаемое значение включаются и интервалы. Text1.Text=Printer.TextHeight("vbzero")

Text2.Text=Printer.TextWidth("vbzero") Tеперь попробуем разобраться, как все это использовать на примере программки Printing. Чтобы у нас было, что выводить на печать, я набросал подобие программки, представляющую собой рабочее места продавца мобильных телефонов. Советую вам скачать ее вверху страницы, чтобы иметь перед глазами, а потом продолжать читать главу.

Создадим новый exe-проект. Первая ее часть представляет собой интерфейс для работы с базой мобильных телефонов: вывод на экран изображения и технических характеристик телефона, две кнопки навигации - вперед и назад и кнопка Печать. Изображение и теххарактеристики грузятся из файлов, имеющих имена 1.jpg и 1.txt, 2.jpg и 2.txt, и так далее, т.е., аналогично программке Tester, которую мы разбирали в Главе 8.

Итак стандартное начало:

Option Explicit

Option Base 1

Объявляем статический одномерный массив для двенадцати строк технических характеристик телефона:

Dim MassiveData(12) As String

Затем несколько необходимых переменных

Dim FileName As String 'для имени загружаемых файлов

Dim F As Long 'для номера свободного файла

Dim X As Long 'для переменной цикло For...Next

Dim QuantityFonts As Long 'для числа найденых шрифтов

Затем процедура загрузки формы. Здесь мы просто изначально устанавливаем имя загружаемого файла - "1" ("1.jpg" и "1.txt") и переходим к созданной нами процедуре загрузки этих файлов DataLoading().

Private Sub Form_Load()

FileName = "1"

DataLoading

End Sub

Private Sub DataLoading()

Загружаем изображение телефона в Image1

Image1.Picture = LoadPicture(App.Path & "\" & FileName & ".jpg")

Восстанавливаем положение Image1 от левой и верхней границы экрана соответственно

Image1.Left = 24

Image1.Top = 128

Центрируем положение картинки в зависимости от того, вертикальная она (Image1.Height > Image1.Width - высота больше ширины) или горизонтальная (Image1.Width > Image1.Height - ширина больше высоты)

If Image1.Width > Image1.Height Then Image1.Top = Image1.Top + (250 - Image1.Height) / 2

If Image1.Height > Image1.Width Then Image1.Left = Image1.Left + (250 - Image1.Width) / 2

Открываем текстовой файл с тем же именем, что и картинка и грузим 12 строк текста в 12 элементов массива

F = FreeFile

Open App.Path & "\" & FileName & ".txt" For Input As #F

For X = 1 To 12

Line Input #F, MassiveData(X)

Тут же выводим содержание массива в Label9. Обратите внимание, что Label9 представляет собой Control Array (по сути - это одномерный массив объекта), т.е. группу лейблов с именем Label9(индекс). По этому индексу мы можем перебирать Label9 в цикле. Делается это так: мы кладем на форму Label9, затем копируем его. VB спрашивает "Создавать Control Array?", ты отвечаешь "Да", после чего на форме появляется копия Label9 с именем Label9(1). Наш же просто лейбл Label9 становится Label9(0). Продолжаем этот процесс до получения нужного количества лейблов в Control Array. А потом, ненужные элементы надо уничтожить. У нас, поскольку мы используем оператор Option Base 1, и элементы массива начинаются с единицы - это Label9(0). Аналогично создается и Control Array и для Label8, куда присваиваются наименования технических характеристик телефона. Для облегчения кода я сделал это присвоение в окне свойств Label8.

Label9(X).Caption = MassiveData(X)

Next X

Close #F

End Sub

В кнопках Command1 и Command2 мы пишем код для смены имени загружаемого файла. Все это опять-таки похоже на программку Tester из Главы 8, и на этом я подробно останавливаться не буду.

Private Sub Command1_Click()

If Val(FileName) > 1 Then

FileName = Str(Val(FileName) - 1)

FileName = Right(FileName, Len(FileName) - 1)

DataLoading

End If

End Sub

Private Sub Command2_Click()

FileName = Str(Val(FileName) + 1)

FileName = Right(FileName, Len(FileName) - 1)

If Dir(App.Path & "\" & FileName & ".txt") <> "" Or Dir(App.Path & "\" & FileName & ".jpg") <> "" Then

DataLoading

Else

FileName = Str(Val(FileName) - 1)

FileName = Right(FileName, Len(FileName) - 1)

DataLoading

End If

End Sub

А вот сейчас мы переходм к тому, ради чего мы все это затеяли. Попробуем подготовить для печать документ. В процедуре кнопки Command3 мы начнем формировать страницу для печати. Сперва объявим кое-какие переменные

Private Sub Command3_Click()

Dim OrientTelefona As Single ' меняет отступ от картинки в зависимости горизонтальная она или вертикальная

Dim Fonts() As String 'одномерный динамический массив для хранения существующих шрифтов

Dim VertCoord As Single 'накапливает сдвиг по вертикали по мере создания строк в документе

Dim NumberFont As Long ' номер шрифта

обнуляем переменную, содержащую количество шрифтов на всякий случай

QuantityFonts = 0

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

For NumberFont = 0 To Printer.FontCount - 1

If Printer.Fonts(NumberFont) = "Arial Cyr" Or Printer.Fonts(NumberFont) = "Times New Roman" _

Or Printer.Fonts(NumberFont) = "Courier New" Or Printer.Fonts(NumberFont) = "MS Sans Serif" Then

QuantityFonts = QuantityFonts + 1

ReDim Preserve Fonts(QuantityFonts)

Fonts(QuantityFonts) = Printer.Fonts(NumberFont)

End If

Next NumberFont

Затем, если хоть один шрифт найден, мы устанавливаем его из первого элемента массива

If QuantityFonts > 0 Then Printer.FontName = Fonts(1)

Ну уж если нет, то в надежде, что какой-то там шрифт по умолчанию в принтер загрузится, продолжаем формировать документ.

Для удобства и наглядности все будем мерять в сантиметрах, поэтому устанавливаем размерность в сантиметрах

Printer.ScaleMode = vbCentimeters

Хочу сказать, что начинать формирование страницы методом Printer.NewPage не надо, иначе первой вылезет пустая страница. У тебя нет еще ни одной страницы, а ты хочешь создавать новую. Вот для второй и т.д. страницы - пожалуйста.

устанавливаем размер шрифта для первой строки

Printer.FontSize = 12

'устанавливаем подчеркивание

Printer.Font.Underline = True

'устананавливаем качество печати - среднее

Printer.PrintQuality = 3

Прижимаем вправо первую строчку с названием фирмы. Для установки положения начала вывода по-горизонтали используется свойство .CurrentX. Что-бы строчка прижалась вправо мы из общей ширины нашего документа Printer.ScaleWidth вычтем длину нашей строчки Printer.TextWidth(Label1.Caption), которую она займет при печати объявленным нами шрифтом:

Printer.CurrentX = Printer.ScaleWidth - Printer.TextWidth(Label1.Caption)

В переменной VertCoord мы будем накапливать сдвиг по вертикали. Сначала запишем в нее, сколько высоты заняла первая строка (вместе с отступами).

VertCoord = Printer.TextHeight(Label1.Caption)

Теперь встраиваем в страницу первую строчку. Никакой печати при этом не происходит. Собственно принтер начинаеn работать только тогда, когда VB посчитает, что формирование документа закончено. Это произойдет, если будет написан оператор Printer.EndDoc, либо если ты выйдешь из программы совсем.

Printer.Print Label1.Caption

'устанавливаем большой размер шрифта для названия модели телефона

Printer.FontSize = 20

'отменяем подчеркивание

Printer.Font.Underline = False

'зато ставим жирный

Printer.Font.Bold = True

'делаем отступ вниз на 1,5 см от первой строчки, меняя вертикальную координату

Printer.CurrentY = VertCoord + 1.5

'выравниваем вторую строчку по-середине

Printer.CurrentX = (Printer.ScaleWidth - Printer.TextWidth(Label9(1).Caption & "Лидер продаж - телефон ")) / 2

'добавляем, сколько высоты мы использовали на вторую строчку вместе с отступами

VertCoord = VertCoord + Printer.TextHeight(Label9(1).Caption) + 1.5

'встраиваем в страницу вторую строчку

Printer.Print "Лидер продаж - телефон " & Label9(1).Caption

'устанавливаем размер шрифта поменьше для заглавия технических характеристик телефона

Printer.FontSize = 14

'добавляем курсив

Printer.Font.Italic = True

'отступаем вниз еще на 2 см

Printer.CurrentY = VertCoord + 2

'добавляем высоту третьей строчки вместе с отступами

VertCoord = VertCoord + Printer.TextHeight(Label4.Caption) + 2

'оставляем 8 см слева под картинку, а остальное справа - под текст

'строчку центрируем на ее Printer.ScaleWidth = 8 см

Printer.CurrentX = (Printer.ScaleWidth - 8 - Printer.TextWidth(Label4.Caption)) / 2

'встраиваем в страницу третью строчку

Printer.Print Label4.Caption

Для печати изображения телефона берем текущую координату по вертикали VertCoord.

Печатаем картинку, центрируя ее на своей площади и меняя пустое расстояние перед ней, в зависимости от того, горизонтальная она (OrientTelefona = 0.5) или вертикальная (OrientTelefona = 2.25). Тогда картинка будет располагаться красиво, по центру выделенной ей площади.

If Image1.Height > Image1.Width Then

OrientTelefona = 2.25

Else

OrientTelefona = 0.5

End If

Встраиваем картинку в наш документ

Printer.PaintPicture Image1.Picture, Printer.ScaleWidth - ScaleX(Image1.Width, vbPixels, vbCentimeters) - OrientTelefona, VertCoord

'отменяем курсив и жирность

Printer.Font.Italic = False

Printer.Font.Bold = False

'устанавливаем размер шрифта еще меньше

Printer.FontSize = 12

'отступаем вниз от 3-ей строки на 1 см

Printer.CurrentY = VertCoord + 1

VertCoord = VertCoord + 1

Теперь, остальные строки - технические данные( с 2-ой по 11-ую) мы встроим в цикле (всего 10 строк) не меняя размеров, жирности и т.п. шрифта. Обратите внимание, что наименование характеристи в Label8(X) и сами характеристики в Label9(X) прописаны отдельно друг от друга и перед каждым установлены свои координаты начала печати Printer.CurrentX и Printer.CurrentY. Тогда печать осуществится красиво, двумя столбиками.

For X = 2 To 11

'отступаем слева по сантиметру

Printer.CurrentX = 1

Printer.CurrentY = VertCoord

Printer.Print Label8(X).Caption

Printer.CurrentX = 5

Printer.CurrentY = VertCoord

Printer.Print Label9(X).Caption

VertCoord = VertCoord + 0.6 'увеличение вертикальной координаты с каждой новой строчкой

Next X

Теперь для акцента на цену телефона, выведем на печать прямоугольник через все страницу. Подробно о рисовании простых графических фигур программным методом мы поговорим в следующей главе. Здесь мы используем метод Line.

VertCoord = VertCoord + 1

Printer.Line (1, VertCoord)-(17.5, VertCoord + 0.7), vbBlack, BF

Printer.CurrentY = VertCoord + 0.1

Printer.CurrentX = 6

'теперь пишем цену

Printer.Font.Bold = True

Printer.Print "Самая лучшая цена: " & Label9(12).Caption & " руб."

Printer.Font.Bold = False

А вот теперь даем команду о завершении формирования страницы и принтер начинает печать:

Printer.EndDoc

End Sub

Но не все хорошо в этом примере. Строка, которая выводит особенности телефона (Label9(8)) длинная и не входит в рамки страницы, а при печати все, что не влезает в страницу безжалостно отсекается и на печать не выводится. Та же проблема возникает при печати неформатированного текста из текстового файла. Попробуйте решить эту проблему самостоятельно. Возможно позже я по этому поводу чего-нибудь напишу, но не здесь, а в Части 3 - "Релизация некоторых задач"

Разбивать текст можно по пробелам. Возможно, ты захочешь использовать функцию InStr.

Функция InStr.

Эта функция используется при текстовом поиске. Она возвращает значение (если совпадение обнаружено)- позицию (номер символа), с которого искомая строка входит в строку, в которой выполняется поиск. Если поиск не удался или строка, в которой проводится поиск - пустая, возвращаемое значение - 0. Ее синтаксис следующий

Числовая переменная=InStr(номер символа, строка поиска, критерий поиска, способ сравнения)

номер символа - необязательный аргумент определяет с какого символа в строке (третьего, десятого и т.п.) надо начинать поиск. Если не задан, поиск начинается с первого символа.

строка поиска - строка, в которой ведется поиск

критерий поиска - искомое строковое выражение

способ сравнения - необязательно. Указывает способ сравнения строк (0-двоичное сравнение, 1 -посимвольное сравнение без учета регистра, 2 - только в Microsoft Access). Если аргумент опущен, способ сранения определяется параметром инструкции Option Compare.

Вот пример поиска фамилии Иванов по по критерию из четырех начальных букв "иван" в массиве A(4) без учета регистра.

Dim A(4) As String

Dim X As Long

A(1) = "Петров"

A(2) = "Сидоров"

A(3) = "Иванов"

A(4) = "Глюкоза"

For X = 1 To 4

If InStr(1, A(X), "иван", 1) > 0 Then

MsgBox "Найден " & A(X) & " в строке " & X

End If

Next X

Удачи!

Copyright © 2005 4us  

Соседние файлы в папке Самоучитель