Can we change printer settings at run time in SSRS 2008?
For example, if a report is on Legal size paper but I want to print on A4 Landscape or Legal at run time, depending on a parameter which is passed in.
The answer is that NO, you cannot unless you write your own solution. The report viewer control does not support this. Your options are either to create a custom printing solution, OR to manipulate your RDLC file to modify the settings manually.
If you decide to modify the RDLC file on the fly, you need to load the RDLC file into memory, modify the XML file to specify the new page settings, then reload the RDLC file in the report viewer.
If you decide to do manual printing, here is some VB.NET code to help you get started:
Dim m_pageSettings As PageSettings 'Stores page settings for printout
Dim m_currentPage As Integer 'Used for index of pages
Private m_pages As New List(Of Stream)() 'Stores a stream for each pages
'Event fires when printDocument starts printing - reset page index to zero
Private Sub PrintDocument1_BeginPrint(ByVal sender As System.Object, ByVal e As System.Drawing.Printing.PrintEventArgs) Handles PrintDocument1.BeginPrint
m_currentPage = 0
End Sub
'Function that prints all the pages included in the report
Private Sub PrintDocument1_PrintPage(ByVal sender As System.Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
Dim pageToPrint As Stream = m_pages(m_currentPage)
pageToPrint.Position = 0
Dim pageMetaFile As Metafile = New Metafile(pageToPrint) 'create an image(metafile) of the report page
Using (pageMetaFile)
'Create a rectangle the size of our report - include margins
' Dim adjustedRect As Rectangle = New Rectangle( _
' e.PageBounds.Left - CType(e.PageSettings.HardMarginX, Integer), _
' e.PageBounds.Top - CType(e.PageSettings.HardMarginY, Integer), _
' e.PageBounds.Width, _
' e.PageBounds.Height)
Dim adjustedRect As Rectangle = New Rectangle( _
e.PageBounds.Left, _
e.PageBounds.Top, _
e.PageBounds.Width, _
e.PageBounds.Height)
e.Graphics.FillRectangle(Brushes.White, adjustedRect) 'Fill rectangle with WHITE background
e.Graphics.DrawImage(pageMetaFile, adjustedRect) 'Draw report in rectangle - this will be printed
m_currentPage = m_currentPage + 1
e.HasMorePages = m_currentPage < m_pages.Count 'If more pages are left - keep processing
End Using
End Sub
'Event fires when PrintDocument queries for PageSettings. Return a copy of m_pagesettings.
Private Sub PrintDocument1_QueryPageSettings(ByVal sender As System.Object, ByVal e As System.Drawing.Printing.QueryPageSettingsEventArgs) Handles PrintDocument1.QueryPageSettings
e.PageSettings = CType(m_pageSettings.Clone, PageSettings)
End Sub
'Render the report in a EMF - This function creates metafiles(images) of each page in the report
Private Sub RenderAllLocalReportPages(ByVal localReport As LocalReport)
Dim deviceInfo As String = CreateEMFDeviceInfo() 'Enhanced MetaFile
Dim warnings As Warning() = Nothing
m_pages.Clear()
localReport.Render("IMAGE", deviceInfo, AddressOf LocalReportCreateStreamCallback, warnings)
End Sub
'Callback function used with RenderAllLocalReportPages
Private Function LocalReportCreateStreamCallback(ByVal name As String, ByVal extension As String, ByVal encoding As Encoding, ByVal mimeType As String, ByVal willSeek As Boolean) As Stream
Dim stream As New MemoryStream()
m_pages.Add(stream)
Return stream
End Function
Private Function CreateEMFDeviceInfo() As String
Dim paperSize As PaperSize = m_pageSettings.PaperSize
Dim margins As Margins = m_pageSettings.Margins
'The device info string defines the page range to print as well as the size of the page.
'A start and end page of 0 means generate all pages.
Return String.Format(CultureInfo.InvariantCulture, "<DeviceInfo><OutputFormat>emf</OutputFormat><StartPage>0</StartPage><EndPage>0</EndPage><MarginTop>{0}</MarginTop><MarginLeft>{1}</MarginLeft><MarginRight>{2}</MarginRight><MarginBottom>{3}</MarginBottom><PageHeight>{4}</PageHeight><PageWidth>{5}</PageWidth></DeviceInfo>", ToInches(margins.Top), ToInches(margins.Left), ToInches(margins.Right), ToInches(margins.Bottom), ToInches(paperSize.Height), ToInches(paperSize.Width))
End Function
'Convert report printing size to inches
Private Shared Function ToInches(ByVal hundrethsOfInch As Integer) As String
Dim inches As Double = hundrethsOfInch / 100.0R
Return inches.ToString(CultureInfo.InvariantCulture) & "in"
End Function
Hopefully this helps.
Related
I tried to follow up with the topic here:
How to connect to OPEN workbook in another instance of Excel
But I ran into a problem,
I am not able grab the new instance name or path.
However I know I have open Excel window in another instance (opened from a SAP system) and when I open VBA editor in that SAP generated Excel file and I type: ? Thisworkbook.Path in immediate window I get nothing, no path is given and thus this solutions does not get the instance path.
What can I do to make it work ?
My issue is that this: Set xlApp = GetObject("C:\Tmp\TestData2.xlsx") is not grabbing the workbook name (including This.workbook.name or activeworkbook.name)
Any idea how else I can make VBA code in instance 1 work with workbook in instance 2?
I only want to save it nothing more, I'm using Saveas option, or at least I try.
Have anyone had a similar issue?
Working with the Excel files downloaded from SAP is always problematic.
You can use the module below and add before the xls.Close SaveChanges:=False this line xls.SaveAs Filename:='Any name that you want after that just place a call in your code after downloading the Excel File with
Call Close_SAP_Excel("TestData2.xlsx")
And it should work fine.
Module:
#If VBA7 Then
Private Declare PtrSafe Function AccessibleObjectFromWindow Lib "oleacc" ( _
ByVal hwnd As LongPtr, ByVal dwId As Long, riid As Any, ppvObject As Object) As Long
Private Declare PtrSafe Function FindWindowExA Lib "user32" ( _
ByVal hwndParent As LongPtr, ByVal hwndChildAfter As LongPtr, _
ByVal lpszClass As String, ByVal lpszWindow As String) As LongPtr
#Else
Private Declare Function AccessibleObjectFromWindow Lib "oleacc" ( _
ByVal hwnd As Long, ByVal dwId As Long, riid As Any, ppvObject As Object) As Long
Private Declare Function FindWindowExA Lib "user32" ( _
ByVal hwndParent As Long, ByVal hwndChildAfter As Long, _
ByVal lpszClass As String, ByVal lpszWindow As String) As Long
#End If
Sub Close_SAP_Excel(ParamArray FileNames())
'Procedure to close files downloaded from SAP and at the same time close the Excel application instance that will be open with them.
Dim ExcelAppSAP As Variant
Dim ExcelFile As Variant
Dim FinishedLoop As Boolean, TimeoutReached As Boolean, FileClosed As Boolean
Dim ReTry As Long
Dim i As Long, x As Long
Set ExcelAppSAP = Nothing
ReTry = 100000 'Used as Timeout 100000 = ~10 seconds
i = 1
'The following loop is executed until excel file is closed.
'Inside of this, there is a For Loop for each Excel Instance and inside of that is another loop
'for each excel inside the instance. If name matches, it is closed.
Do While Not FinishedLoop
If i > ReTry Then
TimeoutReached = True
Exit Do
End If
For Each ExcelFile In GetExcelInstances() 'Function to Get Excel Open Instances
For Each xls In ExcelFile.Workbooks
For x = LBound(FileNames()) To UBound(FileNames())
If xls.Name = FileNames(x) Then
Set ExcelAppSAP = ExcelFile 'Set Instance opened by SAP to variable
'Here add actions if needed. Reference to workbook as xls e.g.: xls.Sheets(1).Range("A1").Copy
xls.Close SaveChanges:=False
FileClosed = True
End If
Next x
Next
Next
If FileClosed Then
FinishedLoop = True
End If
i = i + 1
Loop
ThisWorkbook.Activate
If Not TimeoutReached Then
If FileClosed Then
On Error Resume Next
If ExcelAppSAP.Workbooks.Count = 0 Then
ExcelAppSAP.Quit
End If
Else
MsgBox "Excel application instance from SAP was not closed correctly. Please close it manually or try again.", , "Error"
End If
Else
MsgBox "Max timeout reached", , "Error"
End If
End Sub
Public Function GetExcelInstances() As Collection
Dim guid&(0 To 3), acc As Object, hwnd, hwnd2, hwnd3
guid(0) = &H20400
guid(1) = &H0
guid(2) = &HC0
guid(3) = &H46000000
Set GetExcelInstances = New Collection
Do
hwnd = FindWindowExA(0, hwnd, "XLMAIN", vbNullString)
If hwnd = 0 Then Exit Do
hwnd2 = FindWindowExA(hwnd, 0, "XLDESK", vbNullString)
hwnd3 = FindWindowExA(hwnd2, 0, "EXCEL7", vbNullString)
If AccessibleObjectFromWindow(hwnd3, &HFFFFFFF0, guid(0), acc) = 0 Then
GetExcelInstances.Add acc.Application
End If
Loop
End Function
All,
I have an MS Access database that has some file attachments that I need to programmatically copy to another MS Access table (both tables are linked tables to a SharePoint 2007 list). I have the following code.
Private Sub AddAttachments(rsSource As Recordset, rsDest As Recordset)
Dim rs2Source As Recordset2
Dim rs2Dest As Recordset2
Set rs2Source = rsSource.Fields!Attachments.Value
Set rs2Dest = rsDest.Fields("Attachments").Value
rs2Source.MoveFirst
If Not (rs2Source.BOF And rs2Source.EOF) Then
While Not rs2Source.EOF
rs2Dest.AddNew
rs2Dest!FileData = rs2Source!FileData
rs2Dest.Update
rs2Source.MoveNext
Wend
End If
Set rs2Source = Nothing
Set rs2Dest = Nothing
End Sub
My issue is that when it gets to rs2Dest!FileData = rs2Source!FileData, it keeps giving me an Invalid Argument error. So, if what I am trying to do is possible, how can I adjust my code to read the attachment data from one list and import it into the other list (both linked as linked-tables in an instance of MS Access).
Thanks in advance.
All,
Here is the clunky solution I came up with in case it helps someone else.
First, I needed to access the URLmon library's URLDownloadToFileA function.
Private Declare Function URLDownloadToFileA Lib "urlmon" (ByVal pCaller As Long, ByVal szURL As String, ByVal szfilename As String, ByVal dwreserved As Long, ByVal ipfnCB As Long) As Long
Then, I would use this library to download the file to my disk, upload from my disk, and delete the temporarily stored file as follows:
Private Function DownloadFile(URL As String, LocalFilename As String) As Boolean
DownloadFile = (URLDownloadToFileA(0, URL, LocalFilename, 0, 0) = 0)
End Function
Private Function GetRight(strText As String, FindText As String) As String
Dim i As Long
For i = Len(strText) - Len(FindText) + 1 To 1 Step -1
If Mid(strText, i, Len(FindText)) = FindText Then
GetRight = Mid(strText, i + 1, Len(strText))
Exit For
End If
Next i
End Function
Private Sub AddAttachments(rsSource As Recordset, rsDest As Recordset)
Dim rs2Source As Recordset2
Dim rs2Dest As Recordset2
Set rs2Source = rsSource.Fields!Attachments.Value
Set rs2Dest = rsDest.Fields("Attachments").Value
Dim strDownload As String
Dim strTemp As String
strTemp = Environ$("TEMP")
If Not (rs2Source.BOF And rs2Source.EOF) Then
rs2Source.MoveFirst
If Not (rs2Source.BOF And rs2Source.EOF) Then
While Not rs2Source.EOF
rs2Dest.AddNew
'rs2Dest.Update
'rs2Dest.MoveLast
'rs2Dest.Edit
strDownload = strTemp & "\" & GetRight(rs2Source!FileURL, "/")
Debug.Print DownloadFile(rs2Source!FileURL, strDownload)
rs2Dest.Fields("FileData").LoadFromFile strDownload
rs2Dest.Update
rs2Source.MoveNext
Kill strDownload 'delete the temporarily stored file
Wend
End If
End If
Set rs2Source = Nothing
Set rs2Dest = Nothing
End Sub
I'm sure there's an easier way, but this seem to work for my purposes (albeit in a clunky fashion that is only fitting for the likes of VBA).
Basically I have a string that will looks like this :
<p>HELLO <span style='color:red'>WORLD</span></p>
How would I go about converting this string of HTML into an image? (Bitmap, PNG, etc.)
Does anyone know of any VB.NET tools that will do this? Since this is a string, it cannot read from the DOM as it technically isn't part of the DOM.
My overall purpose is to create an ASPX page that will reading a field containing some HTML from a database, converting that HTML into an image, and the steaming that image on the page by spoofing the ContentType to "image/png", thereby creating a dynamic image that I can use in an RDLC file.
The reason we're displaying HTML as an image in an RDLC file is simply because all of our reports are using ReportViewer version 9.0 which does not support interpreted HTML. Creating a dynamic image based on HTML allows us to display the "formatting" that we want to show directly in the report, which we could not do otherwise, not with such flexibility anyways.
You can render html on the screen using the WebBrowser control, then copy the screen bitmap to am image file.
WebBrowser1.DocumentText = "<p>HELLO <span style='color:red'>WORLD</span></p>"
This code ALMOST works. You need to click the button twice, and it only works properly on the second click. There is a timing issue with grabbing the rendered page you will need to solve. Also, the form must be in front, as it is a screengrab, so only grabs the visible portion of the screen.
Option Strict On
Imports System.Drawing
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim strHTML As String = "<p>HELLO <span style='color:red'>WORLD</span></p>"
WebBrowser1.DocumentText = strHTML
Dim bmp As Bitmap = GetControlImage(WebBrowser1)
Dim strFilename As String = "C:\Junk\Junk.png"
bmp.Save(strFilename, System.Drawing.Imaging.ImageFormat.Png)
End Sub
Private Declare Function BitBlt _
Lib "gdi32.dll" ( _
ByVal hdcDest As IntPtr, _
ByVal x As Int32, _
ByVal y As Int32, _
ByVal Width As Int32, _
ByVal Height As Int32, _
ByVal hdcSrc As IntPtr, _
ByVal xSrc As Int32, _
ByVal ySrc As Int32, _
ByVal dwRop As Int32 _
) As Boolean
Private Const SRCCOPY As Integer = &HCC0020
Function GetControlImage(ctl As Control) As Bitmap
Dim grpInput As Graphics = ctl.CreateGraphics
' Create a compatible bitmap and get its Graphics object
Dim bmpOutput As New Bitmap(ctl.ClientRectangle.Width, ctl.ClientRectangle.Height, grpInput) 'formImage = New Bitmap(frmForm.ClientRectangle.Width, frmForm.ClientRectangle.Height, formGraphics)
Dim grpOutput As Graphics = Graphics.FromImage(bmpOutput)
' Get the target and source device context handles (hDC)
Dim sourceDC As IntPtr = grpInput.GetHdc
Dim targetDC As IntPtr = grpOutput.GetHdc
' Copy the control's client area
BitBlt(targetDC, 0, 0, ctl.ClientRectangle.Width, ctl.ClientRectangle.Height, sourceDC, ctl.ClientRectangle.X, ctl.ClientRectangle.Y, SRCCOPY)
' Release DCs and dispose objects
grpInput.ReleaseHdc(sourceDC)
grpInput.Dispose()
grpOutput.ReleaseHdc(targetDC)
grpOutput.Dispose()
Return bmpOutput
End Function
End Class
wkhtmltopdf also has a a wkhtmltoimage.exe that you can utilize, try http://wkhtmltopdf.org/
Adding "Application.DoEvents" immediately before the instruction "Dim bmp As Bitmap = GetControlImage(WebBrowser1)" seems to solve the problem of having to press the button twice.
I am new to programming in c# and visual basic. I am using visual studio 2010 and I am trying to retrieve some data from a mysql database. Installed using wamp.
I have already set connection to the database by going to 'Project', 'Application Properties', 'Settings'.
I have this error "'mAuto1' is not declared. It may be inaccessible due to its protection level" and I cant seem to solve it.
The code below is for a simple retrieve:
Public Class Form1
Private procAuto As CALCOM.Auto
Private Function Connect_To_Database() As Boolean
Dim mErrorNumQuery As Long
Dim mReturn As Boolean
procAuto = New CALCOM.Auto
procAuto.Connect(mErrorNumQuery)
If mErrorNumQuery = 0 Then
mReturn = True
Else
mReturn = False
End If
Connect_To_Database = mReturn
End Function
Private Function Get_Weight_By_TicketNumber(ByVal mTicketNumber As String, ByRef mAuto1 As Long, ByRef mAuto2 As Long, ByRef mTotalWeight As Long) As Boolean
Dim mErrorNumQuery As Long
Dim mXtr As New CALCOM.xTr
Dim mRec As ADODB.Recordset
Dim mReturn As Boolean
mRec = mXtr.GetList("Select Auto1,Auto2,TotalWeight From txticket Where TicketCode = '" & mTicketNumber & "'", , , mErrorNumQuery)
If mErrorNumQuery = 0 Then
mReturn = True
If mRec.RecordCount <> 0 Then
mRec.MoveFirst()
mRec.MoveFirst()
mAuto1 = mRec.Fields("Auto1").Value
mAuto2 = mRec.Fields("Auto2").Value
mTotalWeight = mRec.Fields("TotalWeight").Value
End If
Else
mReturn = False
End If
Get_Weight_By_TicketNumber = mReturn
End Function
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Label1.Text = mAuto1 <--------------------problem here
End Sub
End Class
This program was just a test to see if I can display results of a mysql query on a form label. I wanted to display results on the click of a button
How do I fix the error? Any help appreciated.
The mAuto1 variant is a local one at Get_Weight_By_TicketNumber function, you can't use it outside the function. If you want, declare a class-level variant and set it to the value of mAuto1.
i am trying to fetch some data from Url using Httpwebrequest/response, i am getting response which i am showing in a msgbox. It show whole HTML contents.
Now my i want to fetch a specific tag(TD tag) value and show all its value in a combobox in vb.net desktop application.
my code to get response from webserver is :
enter code here
Imports System.IO
Imports System.Net
Imports System.Xml
Imports System.Text.Encoder
Public Class login
Private Sub login_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
End
End Sub
Private Sub Panel1_Paint(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Panel1.Paint
End Sub
Private Sub Ok_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Ok.Click
Dim strId As String = txt_uid.Text
Dim strPwd As String = txt_pwd.Text
Dim oEncoder As New System.Text.ASCIIEncoding
Dim postData As String = "UM_username=" + strId
postData += ("&UM_password=" + strPwd)
Dim data As Byte() = oEncoder.GetBytes(postData)
MsgBox(postData)
Dim webStream As Stream
Dim webResponse As String = ""
Dim req As HttpWebRequest
Dim res As HttpWebResponse
Dim Output As String
'Dim Posit1 As Int32
'Dim Posit2 As Int32
req = WebRequest.Create("http://localhost/basic_framework/index.php?menu=login&UM_email=" & strId & "&UM_password=" & strPwd)
req.ContentType = "application/x-www-form-urlencoded"
req.KeepAlive = False
req.Method = "POST"
res = req.GetResponse()
webStream = res.GetResponseStream()
Dim webStreamReader As New StreamReader(webStream)
While webStreamReader.Peek >= 0
Output = webStreamReader.ReadToEnd()
RichTextBox1.Text = Output
Msgbox(Output)
End While
End Sub
End Class
this code get the response from url and show it in a richtextbox or msgbox
Now i want to get a specific tag value (say, td, option values) and show it in a combobox in my vb.net application form dynamically.It would be needed to parse html content then get that tag value . Please suggest me a way......
If parsing needed , how to parse html contents to get only specific tag value in a combobox in vb.net form
Well...if you can be sure that your request returns valid XHTML (which is XML indeed), you might be able to use an XPath expression.
For the most complicated cases (e.g., an AJAX web-site, etc.) you could use HTMLUnit library with iKVM.