المثال رائع لكن أرجوا أن يقوم أحد الإخوة بتنقية الكود
فأنا إريد طباعة التقرير مباشرة فقط
لا أريد الأكواد الأخرى من التحكم بطول التقرير
عملت عدة محاولات لكن دون جدوى
أرجوا المحاولة إخواني
غرضي هو الطباعة المباشرة فقط
و عليكم السلام و رحمة الله و بركاته بعد الاطلاع على التنفيذ الكود يطبع مباشرة فقط انت محتاج تغير اسم الطابعة في الكود الى الطابعة المثبته لديك او يمكنك عمل لوب لجمع الطابعات المثبتة في كومبو بوكس ومن ثم اختيار الطابعة المفضلة للطباعة دعنا نضف كومبوبوكس للواجهة ونسميه Ts_AllPrinters و نستخدم الكود التالي للحصول على اسماء الطابعات المثبتة نستور المرجع التالي اولا
كود :
Imports System.Drawing.Printing
ثم الاجراء التالي
كود :
'اضافة الطابعات الى كومبو الطابعات
Dim Print_name As String
For i As Integer = 0 To PrinterSettings.InstalledPrinters.Count - 1
Print_name = PrinterSettings.InstalledPrinters.Item(i)
Ts_AllPrinters.Items.Add(Print_name)
Next
If My.Settings.PrinterDefultName <> "" Then
Ts_AllPrinters.Text = My.Settings.PrinterDefultName
End If
انا عملت متغير نصي في الاعدادت لاخزن فيه اسم الطابعة المفضلة للطباعة PrinterDefultName ثم االحدث الخاص بالكومبو الكود التالي
كود :
'تحديث الطابعة الافتراضية بتغيرها
Private Sub Ts_AllPrinters_SelectedIndexChanged(sender As Object, e As System.EventArgs) Handles Ts_AllPrinters.SelectedIndexChanged
Try
My.Settings.PrinterDefultName = Ts_AllPrinters.Text
My.Settings.Save()
Catch ex As Exception
MessageBox.Show(ex.Message, "تحديث الطابعة", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, MessageBoxOptions.RightAlign)
شكرا كثيرا أستادنا ابو ليلى
شكرا على تعبك لتقديم الشرح
لقد إستفدت من هذا الكود الجميل لاستدعاء الطابعات
لكن أخي كيف يمكنني أن أجعل الكود يطبع مباشرة فقط
فأنا نحتاج هده الميزة فقط
ولا أريده أن يعدل على طول أو عرض التقرير
لأني برمجة خواريزميات بسيطة للتحكم في طول التقرير ولا أريد أن يتم تعديلها
كل شيئ تمام أخي ما عدا إحتياجي للطباعة المباشرة
السلام عليكم و رحمة الله اخي الكريم المشكلة لدي انا على الاغلب و هي بسبب الاصدارة 2015 حيث حصلت بعض المشاكل اثناء تحديث اللغة و ليس لدي الوقت الكافي لمراجعتها و ايضا مثالك لا يفتح بالكامل لدي فقط استطيع الولوج الى شاشة الاكواد الخاصة بالفورمات على اي حال انا ساقدم شرحا و انت قم فقط بالتطبيق بالنسبة لقاعدة البيانات موجودة لديك في المجلد X86
اولا اعمل مشروع جديد واضف له مديول Module و سميه Demo مثلا وضع الكود التالي فيه
Public Class Demo
Implements IDisposable
Private m_currentPageIndex As Integer
Private m_streams As IList(Of Stream)
Private Function CreateStream(ByVal name As String, ByVal fileNameExtension As String, ByVal encoding As Encoding, ByVal mimeType As String, ByVal willSeek As Boolean) As Stream
Dim stream As Stream = New MemoryStream()
m_streams.Add(stream)
Return stream
End Function
Private Sub Export(ByVal report As LocalReport)
Dim deviceInfo As String = "<DeviceInfo>" &
"<OutputFormat>EMF</OutputFormat>" &
"<PageWidth>8.5in</PageWidth>" &
"<PageHeight>11in</PageHeight>" &
"<MarginTop>0.25in</MarginTop>" &
"<MarginLeft>0.25in</MarginLeft>" &
"<MarginRight>0.25in</MarginRight>" &
"<MarginBottom>0.25in</MarginBottom>" &
"</DeviceInfo>"
Dim warnings As Warning()
m_streams = New List(Of Stream)()
report.Render("Image", deviceInfo, AddressOf CreateStream, warnings)
For Each stream As Stream In m_streams
stream.Position = 0
Next
End Sub
Private Sub PrintPage(ByVal sender As Object, ByVal ev As PrintPageEventArgs)
Dim pageImage As New Metafile(m_streams(m_currentPageIndex))
Dim adjustedRect As New Rectangle(ev.PageBounds.Left - CInt(ev.PageSettings.HardMarginX),
ev.PageBounds.Top - CInt(ev.PageSettings.HardMarginY),
ev.PageBounds.Width,
ev.PageBounds.Height)
m_currentPageIndex += 1
ev.HasMorePages = (m_currentPageIndex < m_streams.Count)
End Sub
Private Sub Print()
If m_streams Is Nothing OrElse m_streams.Count = 0 Then
Throw New Exception("انتبه: لايوجد بيانات لطباعتها.")
End If
Dim printDoc As New PrintDocument()
printDoc.PrinterSettings.PrinterName = My.Settings.PrinterDefultName
If Not printDoc.PrinterSettings.IsValid Then
Throw New Exception("خطأ: لم يتم التعرف على طابعة افتراضية.")
Else
AddHandler printDoc.PrintPage, AddressOf PrintPage
m_currentPageIndex = 0
printDoc.Print()
End If
End Sub
Public Sub Run(ByVal report2 As LocalReport, ByVal pathstr As String, ByVal source_table As DataTable)
Dim report As New LocalReport()
report = report2
report.ReportPath = pathstr
report.DataSources.Add(New ReportDataSource("Ds1", source_table))
Export(report)
Print()
End Sub
Public Sub Dispose() Implements IDisposable.Dispose
If m_streams IsNot Nothing Then
For Each stream As Stream In m_streams
stream.Close()
Next
m_streams = Nothing
End If
End Sub
End Class
End Module
بعد ذلك قم باضافة DataSet سميها Ds1 و اضف بداخلها جدول Tab1 و اضف له الحقول التي تريدها على ان تكون الحقول موافقة لاسماء الحقول التي تريد جلبها من قاعدة البيانات او عرف Dataset و عبئها ببيانات جدول ما حسب رغبتك , لاحظ في الاعلى الكود التالي يحتوي على اسم Dataset المسمى Ds1
كود :
Public Sub Run(ByVal report2 As LocalReport, ByVal pathstr As String, ByVal source_table As DataTable)
Dim report As New LocalReport()
report = report2
report.ReportPath = pathstr
report.DataSources.Add(New ReportDataSource("Ds1", source_table))
Export(report)
Print()
End Sub
الان في الفورم Form1 سنضيف الادوات التالية ComboBox نسميه Ts_AllPrinters لنضيف له الطابعات Button نسميه btnPrint نستخدمه للطباعة المباشرة DataGridView بالاسم DataGridView1 لنعرض البيانات من القاعدة او الجدول الافتراضي
توفيرا للوقت اعطيك كود النموذج Form1 كاملا و هو سهل فقط دقق فيه و حاول التجريب
Public Class Form1
Dim ConStr As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|Db1.mdb"
Dim Ds As New Ds1
Dim Tb1 As New DataTable("Tb1")
Dim con As New OleDbConnection(ConStr)
Dim _DataAdapter As OleDbDataAdapter
Dim _Select As String = ""
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
_Select = "Select id, namee, phone FROM Tb1"
_DataAdapter = New OleDbDataAdapter(_Select, con)
_DataAdapter.Fill(Ds.Tab1)
DataGridView1.DataSource = Ds.Tab1
'اضافة الطابعات الى كومبو الطابعات
Dim Print_name As String
For i As Integer = 0 To PrinterSettings.InstalledPrinters.Count - 1
Print_name = PrinterSettings.InstalledPrinters.Item(i)
Ts_AllPrinters.Items.Add(Print_name)
Next
If My.Settings.PrinterDefultName <> "" Then
Ts_AllPrinters.Text = My.Settings.PrinterDefultName
End If
End Sub
Private Sub btnPrint_Click(sender As Object, e As EventArgs) Handles btnPrint.Click
ReportPath()
'الغاء الاجراء في حال لم يكن هناك مسار للتقرير
If My.Settings.CashReportAppTh = "" Or IsNothing(My.Settings.CashReportAppTh) Then
MessageBox.Show("حدد مسار التقرير بشكل صحيح", "طباعة الدفعة بشكل مباشر", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, MessageBoxOptions.RightAlign)
Exit Sub
End If
Try
Dim report As New LocalReport()
Dim _Path As String = My.Settings.CashReportAppTh
Dim _Print As New Demo.Demo
_Print.Run(report, _Path, Ds.Tab1)
Catch ex As Exception
MessageBox.Show(ex.Message, "طباعة الدفعة بشكل مباشر", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, MessageBoxOptions.RightAlign)
End Try
End Sub
Private Sub ReportPath()
Try
If My.Settings.CashReportAppTh = "" Then
'فتح مسار ملف التقرير
Dim OpenFd As New OpenFileDialog
Dim Report1 As String = Nothing 'مسار التقرير
Dim ReportName As String = Nothing 'اسم التقرير
'-------------------------------------------------------------
OpenFd.Filter = "Microsoft Reports Files (*.rdlc)|*.rdlc"
OpenFd.FilterIndex = 1
OpenFd.RestoreDirectory = True
'-------------------------------------------------------------
If OpenFd.ShowDialog = Windows.Forms.DialogResult.OK Then
Report1 = OpenFd.FileName 'مسار التقرير
ReportName = OpenFd.SafeFileName 'اسم التقرير
End If
'تخزين مسار التقرير في اعدادت البرنامج
If Not IsNothing(Report1) Or Report1 = "" Then
'اذا كان مسار التقرير صحيحا يتم تخزين المسار في الاعدادت
If ReportName = "Report1.rdlc" Then
My.Settings.CashReportAppTh = Report1
My.Settings.Save()
Else
MessageBox.Show("التقرير المحدد ليس صحيحا حدد التقرير التالي " & vbCrLf & " Report1.rdlc ", " تحديد التقرير ", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, MessageBoxOptions.RightAlign)
Exit Sub
End If
End If
End If
Catch ex As Exception
End Try
End Sub
'تحديث الطابعة الافتراضية بتغيرها
Private Sub Ts_AllPrinters_SelectedIndexChanged(sender As Object, e As System.EventArgs) Handles Ts_AllPrinters.SelectedIndexChanged
Try
My.Settings.PrinterDefultName = Ts_AllPrinters.Text
My.Settings.Save()
Catch ex As Exception
MessageBox.Show(ex.Message, "تحديث الطابعة", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, MessageBoxOptions.RightAlign)
End Try
End Sub
End Class
في اعدادت البرنامج عرف متغيرين نصيين هم على التوالي
اذ يجب ان يكون التقرير مخزن لديك في مجلد البرنامج لاحظ في الاجراء المسمى ReportPath انني قمت بطلب مسار التقرير لتخزينه في الاعدادت وكذلك لاحظ انني قمت بمطابقة اسم التقرير حيث افترضت ان اسمه Report1.rdlc فاذا كان اسم التقرير لديك غير ذلك غيره بما يناسبك
بالنسبة لقاعدة البيانات كما تلاحظ من الاكواد اسمها Db1 فيها جدول واحد Tb1 فيه 3 حقول id,namee,phone
بالنسبة لتصميم التقرير اضف تقرير للبرنامج و غذيه من Datatset المسمى Ds1
من ثم احفظ البرنامج و اعمل Build و تأكد من ان Report1.rdlc قد اضيف الى مجلد البرنامج
الان قم بتشغيل البرنامج و من ثم حدد الطابعة المناسبة لك من قائمة الطابعات عند محاولة الطباعة سيطلب منك تحديد مسار التقرير لاول مرة ليتم تخزينه في الاعدادت ومن ثم سيقوم بالطباعة مع ملاحظة ان كان الجدول لا يحتوي على بيانات سيوقف عملية الطباعة و يعطيك رسالة تنبيه اعتقد ان هذا كل شيئ
اعذرني على تقصيري ان محاولة التعديل على مثالك و اعادة رفعه ستكون دون جدوى بسبب وجود مشاكل لدي
أستاذي الكريم أبو ليلى
شرحك وافي و أكثر من مفهوم الحمد لله
مثالك شغال و الأكواد كلها شغالة كما قمت بالشرح
أشكرك على المجهود و الوقت الذي ضيعته في كتابة هذه السطور
جزاك الله كل خير
فلو تكرمت أخي الكريم و منحتني كود الطباعة المباشرة فقط
فقط دون قواعد بيانات
دون DataSet
دون التحكم في طول التقرير
ودون أي إضافات مثل إختيار الطابعة
أريد فقط طباعة Report1 مباشرة
هلا اخي يمكن انا لم ما انتبهت لطلبك
اذا كنت تريد فقط طباعة بيانات ثابتة دون الحاجة لمصدر بيانات لماذا لا تقم باستخدام PrintDocument
و تستخدم دوال الرسم لتنفيذ المطلوب
ام انك مصر على استخدام Report.Rdlc