Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  | Правила  

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » VBA - Организация печати в VBA 2008 ExpresEdition

Ответить
Настройки темы
VBA - Организация печати в VBA 2008 ExpresEdition

Новый участник


Сообщения: 5
Благодарности: 0

Профиль | Отправить PM | Цитировать


Привет всем! Помогите разобраться с организацией печати в VBA 2008, а то методы, которые применялись в VB6 не работают. Совсем не работают....
Суть проблемы:
Есть форма с множеством ТекстБоксов с Лейблами в которые выводятся результаты некоторых вычислений.
Нужно, что-бы при нажатии в меню пункта "Печать" принтер печатал страницу А4 с данными из тех самых ТекстБоксов + некоторую картинку из папки Resources проекта и чтоб это все как-то выглядело красиво.
С VBA 2008 как-то с помощью Интернета разобрался, а вот с выводом на печать не могу - не могу найти толковой литературы по VBA 2008.
Есть справочник по VBA 2005. Кое-что работает а кое-что нет.
По рекомендациям из данного справочника пока-что получилось вот что:

Начало:
Option Explicit On
Imports System.IO
Imports System.Drawing.Printing

Public Class Form1
.
.
.
. Private Sub ToolStripMenuItem5_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToolStripMenuItem5.Click
If PrintDialog1.ShowDialog() = Windows.Forms.DialogResult.OK Then
Printing()
End If "Вызов диалогового окна "Печать", ели нажали "Печать" то переходим к формированию страницы
End Sub

Private Sub Printing()

PrintDocument1.DefaultPageSettings.Margins = New Margins(150, 150, 150, 150) "Установки принтера"
PrintDocument1.DefaultPageSettings.Landscape = False

А здесь непонятно что писать.......

Try
PrintDocument1.Print() (насколько я понял из справочника, то данная команда запускает процесс печати)
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub

Отправлено: 20:14, 29-09-2010

 

Аватара для Delirium

Ветеран


Сообщения: 5624
Благодарности: 936

Профиль | Отправить PM | Цитировать


Так, может, речь все таки идет о Visual Basic .Net , а не о VBA? VBA используется в продуктах MS office для написания макросов. VB.NET - для написания приложений.
Для печати есть много способов - можно использовать встроенный Report Viewer, и создать там нужный отчет. Можно использовать просто Me.Print() - напечатает текущую форму. Можно использовать сторонние создатели отчетности, такие как Fast Report. Можно, в конце концов, формировать вручную отчет в Word или Excel.

-------

Пройденные курсы:
[Microsoft №10174 Sharepoint], [SharePoint]
Мои проекты:[CheckAdmins], [NetSend7], [System Uptime], [Remote RAdmin LogViewer],[Netdom GDI], [Holidays - напоминалка о днях рождения]

А я офис-гуру :)


Отправлено: 01:18, 30-09-2010 | #2



Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.

Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля.


Новый участник


Сообщения: 5
Благодарности: 0

Профиль | Отправить PM | Цитировать


Цитата Delirium:
Так, может, речь все таки идет о Visual Basic .Net , а не о VBA? »
Речь идет о VISUAL BASIC 2008 EXPRESS EDITION из пакета VISUAL STUDIO 2008.
Раньше, например в VB 6 для формирования страницы для вывода на печать использовался оператор Printer, с помощью которого задавались шрифт, отступы, положение на странице и т. д.:

Printer.Print "Текст" & Label().Caption
Printer.EndDoc,
после чего принтер начинал печатать.
Здесь же таких операторов и в помине нет. Есть похожие, но как их использовать - фиг знает....

Отправлено: 17:02, 03-10-2010 | #3


Ветеран


Сообщения: 3320
Благодарности: 916

Профиль | Отправить PM | Цитировать


Здесь ftp://ftp.charlespetzold.com/ProgWinVB/Lines Curves and Area Fills/PrintableForm/PrintableForm.vb пример организации печати формы по клику.
Если приложение реализовать с нуля можно прямо брать и наследоваться от класса PrintableForm, а не как по умолчанию студия предлагает от Form.
Для уже написанного проекта можно воспользоваться и этим способом (попутно устраняя все замечания студии) или скопировать только необходимы функционал из примера, а именно
Код: Выделить весь код
        Dim prndoc As New Printing.PrintDocument() 'Создаём объект печати
        prndoc.DocumentName = Text '"Hello"	'Названия задание печати, берётся с заголовка формы
        AddHandler prndoc.PrintPage, AddressOf PrintDocumentOnPrintPage	'назначить процедуру подготовки документа
        prndoc.Print()'Выполнить печать на принтере по умолчанию, никакого диалога на выбор принтера (при наличии нескольких) не предлагается.
‘Во избежание перевода бумаги рекомендую воспользоваться виртуальным принтером печающий в PDF файл
Это сообщение посчитали полезным следующие участники:

Отправлено: 18:05, 03-10-2010 | #4


Новый участник


Сообщения: 5
Благодарности: 0

Профиль | Отправить PM | Цитировать


Цитата Admiral:
AddHandler prndoc.PrintPage, AddressOf PrintDocumentOnPrintPage 'назначить процедуру подготовки документа »
Можно подробнее о процедуре подготовки документа?
После ввода куска кода (где описывается та самая процедура PrintDocumentOnPrintPage) из
Цитата Admiral:
ftp://ftp.charlespetzold.com/ProgWinVB/Lines Curves and Area Fills/PrintableForm/PrintableForm.vb »
через всю страницу печатаются две диагональные линии крестом.... А нужно чтоб печатался выводимый в ТекстБокс текст. Как добавить в процедуру подготовки TextBox.Text?
Обидно, что приложение полностью готово и выполняет полностью те физические расчеты, которые было нужно, осталось как-то все это выводить на печать, а печатать полностью всю форму как-то не профессионально. Обязательно Майкрософт и Бил Гейтс максимально все усложнят (Само приложение написалось на ура за 2-3 дня, а вот с выводом на печать уже как месяц воюю. ).

Отправлено: 21:58, 04-10-2010 | #5


Ветеран


Сообщения: 3320
Благодарности: 916

Профиль | Отправить PM | Цитировать


Код: Выделить весь код
    Sub PrintDocumentOnPrintPage(ByVal obj As Object, _
                             ByVal ppea As Printing.PrintPageEventArgs)
        Dim grfx As Graphics = ppea.Graphics    'Задаём контекст печати. Через объект grfx будет формироватся страница
        Dim szf As SizeF = grfx.VisibleClipBounds.Size    'взять допустимые размеры страницы
        DoPage(grfx, Color.Black, CInt(szf.Width), CInt(szf.Height))    'передать контекст, цвет шрифта и допустимые размеры в процедуру DoPage, сейчас там рисуется только Х, однако данную процедуру можно переназначить в наследниках
    End Sub
Пример ниже берёт текст из ячеек ListView, аналогично можно работать и с TextBox. Форматировать страницу можно через табуляцию (vbTab) и перенос строки (vbLf).
Пример использования PrintableForm к ранее написанной форме >>

Предположим есть некая форма (в примере ниже собирающая информацию о локальных дисках)
>>
Код: Выделить весь код
Imports System
Imports System.Drawing
Imports System.Windows.Forms

Class AbstractForm
    Inherits Form
    Dim VolumeListView As New ListView
    Shared Sub Main()
        Application.Run(New AbstractForm)
    End Sub
    Sub New()
        Text = "Sample"
        BackColor = SystemColors.Window
        ForeColor = SystemColors.WindowText
        ResizeRedraw = True

        With VolumeListView
            .Parent = Me
            .Location = Point.Empty
            .Size = New Size(ClientSize.Width, ClientSize.Height \ 2)
            .View = View.Details
            .HeaderStyle = ColumnHeaderStyle.Clickable
            .FullRowSelect = True
            .MultiSelect = True
            .BorderStyle = BorderStyle.Fixed3D
            '.Dock = DockStyle.Fill
            .Columns.Add("Volume")
            .Columns.Add("Layout")
            .Columns.Add("Type")
            .Columns.Add("File System")
            .Columns.Add("Status")
            .Columns.Add("Capacity")
            .Columns.Add("Free Space")
            .Columns.Add("% Free")
        End With

        Dim Drives As IO.DriveInfo() = IO.DriveInfo.GetDrives()
        For Each Drive In Drives
            If Drive.IsReady Then
                Dim item1 As ListViewItem = New ListViewItem(New String() {Drive.Name})
                With item1.SubItems
                    .Add("") '.Add("Simple") 'ToDo
                    .Add(Drive.DriveType.ToString) 'Some other type req(see diskmgmt.msc)
                    .Add(Drive.DriveFormat)
                    .Add("") 'ToDo'.Add("Healthy") 'ToDo
                    .Add(Math.Ceiling(Drive.TotalSize / 1024) & " KB")
                    .Add(Math.Ceiling(Drive.AvailableFreeSpace / 1024) & " KB") ' (Drive.TotalFreeSpace)
                    .Add(Math.Ceiling(100 * Drive.AvailableFreeSpace / Drive.TotalSize) & " %")
                End With
                VolumeListView.Items.AddRange(New ListViewItem() {item1})
            End If
        Next
    End Sub
    Protected Overrides Sub OnResize(ByVal re As EventArgs)
        VolumeListView.Size = New Size(ClientSize.Width, VolumeListView.Size.Height)
    End Sub
End Class

Допустим потребовалось вывести изображаемую информацию на печать. Код формы был создан вручную, а не сгенерирован студией, по этому переделываем приложение по первому способу - заменяем наследование от Form на наследование от PrintableForm. В этом случаи в точки входа потребуется добавить ключевое слово Shadows выйдет так Shared Shadows Sub Main(). В свойствах проекта так же нужно поменять точку входа на имя класса (в данном примере на AbstractForm).
Если сейчас запустить проект кроме "Х" на всей форме ничего не поменяет (а на печать только этот Х и будет отправлен). Поэтому переназначаем процедуру DoPage для формы.
Именно здесь будет формироваться страница. Помимо этого она будет отображаться на самой форме - очень удобно если нужна форма предварительного просмотра.
В данном пример, сам сформированный текст будет скрыт за ListView, а вот картинка %WinDir%\Gone Fishing.bmp будет видна из ListView.
Если в системной директории данного файла нет (система не ХР или файл просто удалён) данную строчку надо закомментировать, проверка на отсутствие не проводится, или указать путь к своему графическому файлу.

Если на рабочей формы никакого предварительного просмотра не надо, просто переназначаем событие OnPaint (в примере ниже раскомментируем соответственные строчки, кроме MyBase.OnPaint(pea)).
В результате получим
Код: Выделить весь код
Imports System
Imports System.Drawing
Imports System.Windows.Forms

Class AbstractForm
    Inherits PrintableForm
    Dim VolumeListView As New ListView
    Shared Shadows Sub Main()
        Application.Run(New AbstractForm)
    End Sub
    Sub New()
        Text = "Sample"
        BackColor = SystemColors.Window
        ForeColor = SystemColors.WindowText
        ResizeRedraw = True

        With VolumeListView
            .Parent = Me
            .Location = Point.Empty
            .Size = New Size(ClientSize.Width, ClientSize.Height \ 2)
            .View = View.Details
            .HeaderStyle = ColumnHeaderStyle.Clickable
            .FullRowSelect = True
            .MultiSelect = True
            .BorderStyle = BorderStyle.Fixed3D
            '.Dock = DockStyle.Fill
            .Columns.Add("Volume")
            .Columns.Add("Layout")
            .Columns.Add("Type")
            .Columns.Add("File System")
            .Columns.Add("Status")
            .Columns.Add("Capacity")
            .Columns.Add("Free Space")
            .Columns.Add("% Free")
        End With

        Dim Drives As IO.DriveInfo() = IO.DriveInfo.GetDrives()
        For Each Drive In Drives
            If Drive.IsReady Then
                Dim item1 As ListViewItem = New ListViewItem(New String() {Drive.Name})
                With item1.SubItems
                    .Add("") '.Add("Simple") 'ToDo
                    .Add(Drive.DriveType.ToString) 'Some other type req(see diskmgmt.msc)
                    .Add(Drive.DriveFormat)
                    .Add("") 'ToDo'.Add("Healthy") 'ToDo
                    .Add(Math.Ceiling(Drive.TotalSize / 1024) & " KB")
                    .Add(Math.Ceiling(Drive.AvailableFreeSpace / 1024) & " KB") ' (Drive.TotalFreeSpace)
                    .Add(Math.Ceiling(100 * Drive.AvailableFreeSpace / Drive.TotalSize) & " %")
                End With
                VolumeListView.Items.AddRange(New ListViewItem() {item1})
            End If
        Next
    End Sub
    Protected Overrides Sub OnResize(ByVal re As EventArgs)
        VolumeListView.Size = New Size(ClientSize.Width, VolumeListView.Size.Height)
    End Sub
    Protected Overrides Sub DoPage(ByVal grfx As System.Drawing.Graphics, ByVal clr As System.Drawing.Color, ByVal cx As Integer, ByVal cy As Integer)

        Dim text2Print As String = vbNullString
        For Each Column As ColumnHeader In VolumeListView.Columns
            text2Print = text2Print & Column.Text & vbTab
        Next

        text2Print = text2Print & vbLf

        For Each ListItem As ListViewItem In VolumeListView.Items
            For Each SubItem As ListViewItem.ListViewSubItem In ListItem.SubItems
                text2Print = text2Print & SubItem.Text & vbTab
            Next SubItem
            text2Print = text2Print & vbLf
        Next ListItem

        grfx.DrawString(text2Print, Font, New SolidBrush(clr), New Point(cx / 20, cy / 20))

        grfx.DrawImage(New Bitmap(System.IO.Path.Combine(Environment.GetEnvironmentVariable("windir"), "Gone Fishing.bmp")), New Point(cx / 2, cy / 6))

    End Sub
    'Protected Overrides Sub OnPaint(ByVal pea As System.Windows.Forms.PaintEventArgs)
    ''MyBase.OnPaint(pea)
    'End Sub
End Class


P.S.
PrintableForm печатает только на одну страницу. Разбивку по страницам не производит. Всё что не поместилось отсекается.
Это сообщение посчитали полезным следующие участники:

Отправлено: 15:28, 05-10-2010 | #6


Новый участник


Сообщения: 5
Благодарности: 0

Профиль | Отправить PM | Цитировать


Огромное спасибо, Admiral, !!!
С выводом на печать ТекстБоксов разобрался. Все прекрасно работает.
Вы писали
Цитата Admiral:
Если в системной директории данного файла нет (система не ХР или файл просто удалён) данную строчку надо закомментировать, проверка на отсутствие не проводится, или указать путь к своему графическому файлу. »
.
Как правильно здесь
Цитата Admiral:
grfx.DrawImage(New Bitmap(System.IO.Path.Combine(Environment.GetEnvironmentVariable("windir"), "Gone Fishing.bmp")), New Point(cx / 2, cy / 6) »
прописать путь к графическому файлу, а то студия опять матерится.
Как только разберусь с выводом на печать изображения, напишу полный отчет .

Отправлено: 19:20, 05-10-2010 | #7


Ветеран


Сообщения: 3320
Благодарности: 916

Профиль | Отправить PM | Цитировать


CODE43, эквивалент с абсолютным путём grfx.DrawImage(New Bitmap("C:\windows\Gone Fishing.bmp"), New Point(cx / 2, cy / 6)) для систем установленных на диск С и не с переименованной системной папкой.

Отправлено: 19:35, 05-10-2010 | #8


Новый участник


Сообщения: 5
Благодарности: 0

Профиль | Отправить PM | Цитировать


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

Вставляем в меню объект ToolStripMenuItem, называем его «Печать», Вставляем в проект объект PrintDialog.

Описываем процедуру выбора пункта «Печать»:

Private Sub ToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToolStripMenuItem5.Click
If PrintDialog1.ShowDialog() = Windows.Forms.DialogResult.OK Then
Pechat() ‘При выборе в меню приложения пункта «Печать»
выводится стандартное диалоговое окно для выбора
принтера. Если в диалоге нажать «Печать» то
запускается процедура Pechat ’
End If
End Sub

Собственно, сама процедура:

Private Sub Pechat()
Dim prndoc As New Printing.PrintDocument
prndoc.DocumentName = Text
AddHandler prndoc.PrintPage, AddressOf PrintDocumentOnPrintPage
prndoc.Print()
End Sub

Private Sub PrintDocumentOnPrintPage(ByVal obj As Object, ByVal ppea As PrintPageEventArgs)
Dim grfx As Graphics = ppea.Graphics
Dim szf As SizeF = grfx.VisibleClipBounds.Size
DoPage(grfx, Color.Blue, CInt(szf.Width), CInt(szf.Height))
End Sub

Процедура DoPage формирования страницы для вывода на печать:

Private Sub DoPage(ByVal grfx As System.Drawing.Graphics, ByVal clr As System.Drawing.Color, ByVal cx As Integer, ByVal cy As Integer)
Dim Text2print As String = vbNullString
Dim Font As New Font("Courier New", 14) ‘Шрифт и его размер для
печати’
Text2print = vbTab & vbTab & "Здесь можна напечатать заглавие страницы по центру" & vbLf
Text2print = Text2print & Label1.Text & vbTab & "Какой нибудь текст" & vbTab & TextBox1.Text & vbTab & "Еще какой нибудь текст" & vbLf
Text2print = Text2print & “И так далее, собственно и формируем то что нужно для вывода на печать ”

grfx.DrawString(Text2print, Font, New SolidBrush(clr), New Point(cx / 20, cy / 20)) ‘Печатаем сформированый текст’
grfx.DrawImage(New Bitmap("C:\Папка\Картинка.jpg"), New Point(cx / 4, cy / 3)) ‘Печатаем картинку приблизительно по центру листа (зависит от сх и су)’
End Sub

Отправлено: 19:42, 06-10-2010 | #9



Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » VBA - Организация печати в VBA 2008 ExpresEdition

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
2008 R2 - сервер печати на 2008 сервере edikst Windows Server 2008/2008 R2 2 02-07-2010 12:49
Конкурс - Windows 7 в корпоративной среде. Часть 2: Организация системы печати OSZone Microsoft Windows 7 0 22-11-2009 08:30
[решено] Проблема при печати hp 1018; не очищается очередь печати mirracle Непонятные проблемы с Железом 13 20-01-2007 23:52
Аудит печати на сервере печати под windows 2003 eggdrop Microsoft Windows NT/2000/2003 1 03-10-2006 12:58




 
Переход