Report Parameter Value not set error VB.NET - sql

I am making a small application in VB to export a report from a server to a PDF. I have tested it with a report without parameters, and it worked fine so I know the URLs and everything are correct. But the parameters are not working, and I have Googled extensively and tried everything. I've tried both an array and a list of parameters (both shown in the code), and fiddled with every setting possible in the SSRS Report builder as far as hiding parameters goes. The buyer and supplier are chosen from a drop down list. The error always happens when I finally execute the SetParameters method. If anyone has any ideas I greatly appreciate it.
Dim report As ServerReport = New ServerReport()
'(setting up url stuff)
'use a list for parameters
Dim parameterList As New Generic.List(Of ReportParameter)
parameterList.Add(New ReportParameter("buyer", buyer, True))
parameterList.Add(New ReportParameter("supplier", supplier, True))
parameterList.Add(New ReportParameter("quoteDate", quoteDate.ToString, True))
parameterList.Add(New ReportParameter("reqDate", reqDate.ToString, True))
parameterList.Add(New ReportParameter("user", username, True))
'use an array for parameters
Dim params(4) As ReportParameter
params(0) = New ReportParameter("buyer", buyer, False)
params(1) = New ReportParameter("supplier", supplier, False)
params(2) = New ReportParameter("quoteDate", quoteDate.ToString, False)
params(3) = New ReportParameter("reqDate", reqDate.ToString, False)
params(4) = New ReportParameter("user", username, False)
report.SetParameters(params)
report.Refresh()
'for testing
Dim reportData As Byte() = report.Render("PDF")
System.IO.File.WriteAllBytes("C:\Users\....." & reportName & ".pdf", reportData)

Related

SSRS -parameters sent from VB.NET Code to SSRS reports are not being recognized ,VB.NET and SSRS have different providers in connection string

We have a VB.NET application from which parameter are passed to SSRS reports with arabic content ,our database is IBM DB2.There are two different connection strings with different providers ,in SSRS we use the below connection string as this is printing arabic text in correct order,if i use IBMDASQL.DataSource.1 provider arabic text is rendered in reverse
Provider=Microsoft OLE DB Provider for DB2;User ID=<your used id>;Initial Catalog=dbsys2;Network Transport Library=TCP;Host CCSID=20420;PC Code Page=1256;Network Address=S44CB295;Network Port=446;Package Collection=VEHICLE;Default Schema=VEHICLE;Process Binary as Character=False;Units of Work=RUW;Default Qualifier=VEHICLE;DBMS Platform=DB2/AS400;Persist Security Info=False;Connection Pooling=True
In VB.NET code we use this connection string ,this is a legacy application and i cannot change the provider for this as in SSRS
<add name="ConnStr" connectionString="Provider = IBMDASQL.DataSource.1;Persist Security Info = True;Data Source = SYSPRD01;Default Collection = VEHICLE;Convert Date Time To Char = FALSE;Use SQL Packages = False;Add Statements To SQL Package = False;User ID = <your user id>; Password =<your password>" />
When I try to pass parameters from VB.NET code to SSRS I get the below error
“This report requires a default or user-defined value for the report parameter 'prsFRANCHISE'. To run or subscribe to this report, you must provide a parameter value.” If both connection strings have same provider IBMDASQL.DataSource.1 i am able to render the report succesfully ,only thing is arabic words are in reverse .
I tried to look for setting connection string in vb.net code behind just before i call render report, but there are no methods provided for ServerReport to set connection string
I set parameters using this code
**report.ReportServerUrl = New System.Uri(ldtReportParameter.Rows(0).Item("RMREPTSERV").ToString.Trim)
report.ReportPath = ldtReportParameter.Rows(0).Item("RMREPTPATH").ToString.Trim
laIndividualParameters(0) = New ReportParameter("prsFRANCHISE", row.Cells(4).Text.ToString().Trim(), False)
laIndividualParameters(1) = New ReportParameter("prsBRAN", row.Cells(5).Text.ToString().Trim(), False)
laIndividualParameters(2) = New ReportParameter("prsDEPT", row.Cells(6).Text.ToString().Trim(), False)
laIndividualParameters(3) = New ReportParameter("prsPRNO", row.Cells(3).Text.ToString().Trim(), False)
laIndividualParameters(4) = New ReportParameter("prsCopy", row.Cells(2).Text.ToString().Trim(), False)
report.SetParameters(laIndividualParameters)
ServerExport(report)
lsPrintStatus = Print(row.Cells(9).Text.ToString().Trim(), liNumberofCopies)**
This is my ServerExport method
Private Sub ServerExport(ByVal report As ServerReport)
Try
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)()
Dim pageStream As Stream
Dim firstPageParameters As NameValueCollection = New NameValueCollection()
firstPageParameters.Add("rs:PersistStreams", "True")
firstPageParameters.Add("rs:Command", "ClearSession")
Dim nonFirstPageParameters As NameValueCollection = New NameValueCollection()
nonFirstPageParameters.Add("rs:GetNextStream", "True")
pageStream = report.Render("IMAGE", deviceInfo, firstPageParameters, "image/jpeg", ".jpeg")
While pageStream.Length > 0
m_streams.Add(pageStream)
pageStream = report.Render("IMAGE", deviceInfo, nonFirstPageParameters, "image/jpeg", ".jpeg")
End While
Catch ex As Exception
Master.AlertMessageBox(ex.Message)
End Try
End Sub
I get error in pageStream = report.Render("IMAGE", deviceInfo, firstPageParameters, "image/jpeg", ".jpeg")
where it is unable to recognize paraemeter passed
The last two parameters in the .Render method are out parameters. Meaning you'd have to supply a local variable for the method to assign data to.
So change:
pageStream = report.Render("IMAGE", deviceInfo, firstPageParameters, "image/jpeg", ".jpeg")
To:
Private mime As String
Private extension As String
pageStream = report.Render("IMAGE", deviceInfo, firstPageParameters, mime, extenstion)

External images not loading in RDLC report: Windows Forms Application VB.net

I'm working on a windows forms application, using vb.net and microsoft sql server as backend. As for the reports, I'm using microsoft's rdlc, which has been quite satisfactory for me until I was struck with this distinct problem.
So, in the report I'm using external images, which are loaded through local filepaths, passed as parameters. I retrieve these paths from the database and pass it to the report. This method worked for me for a long time, until it stopped working. Now the case is, that the external images are not loading in the report (a red cross is displayed instead of the image). As far as I feel, this problem has something to do with permissions on my PC because the same code and configurations worked for me before, but I'm not able to resolve it. I have searched everywhere to no end and would definitely want assistance.
My code for the report is:
Try
With Me.ReportViewer1.LocalReport
.DataSources.Clear()
.ReportPath = Application.StartupPath & "\RptArticle.rdlc"
.EnableExternalImages = True
Dim imagepathstring As String = System.IO.Path.Combine(folder & "\ArticlePics", imagepath)
Dim imgparameter As New ReportParameter
imgparameter = New ReportParameter("ImagePath", "file://" & imagepathstring, True)
.SetParameters(imgparameter)
Dim barpathstring As String = System.IO.Path.Combine(folder & "\BarCode", barpath)
Dim barcode As New ReportParameter("Barcode", "file://" & barpathstring, True)
.SetParameters(barcode)
.DataSources.Add(New Microsoft.Reporting.WinForms.ReportDataSource("DSArticleAccessory", Accdt))
.DataSources.Add(New Microsoft.Reporting.WinForms.ReportDataSource("DSArticleSize", AccSdt))
.DataSources.Add(New Microsoft.Reporting.WinForms.ReportDataSource("DSArticleColour", AccCdt))
.DataSources.Add(New Microsoft.Reporting.WinForms.ReportDataSource("DSArticleColour", AccCdt))
.DataSources.Add(New Microsoft.Reporting.WinForms.ReportDataSource("DSArticle", dt))
End With
Me.ReportViewer1.ZoomMode = ZoomMode.PageWidth
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
Me.ReportViewer1.RefreshReport()
When I load the report, the output is:
Warning: Images with external URL references will not display if the report is published to a report server without an UnattendedExecutionAccount or the target image(s) are not enabled for anonymous access. (rsWarningFetchingExternalImages)
Warning: The value of the MIMEType property for the image ‘Image1’ is “application/octet-stream”, which is not a valid MIMEType. (rsInvalidMIMEType)
Warning: The value of the ImageData property for the image ‘Image1’ is “”, which is not a valid ImageData. (rsInvalidExternalImageProperty)
Warning: The value of the MIMEType property for the image ‘Image2’ is “application/octet-stream”, which is not a valid MIMEType. (rsInvalidMIMEType)
Warning: The value of the ImageData property for the image ‘Image2’ is “”, which is not a valid ImageData. (rsInvalidExternalImageProperty)
The thread 0x3948 has exited with code 0 (0x0).
Instead of using external images, you can pass your images as string to your report as parameters.
Convert your image to Base64 string first using this:
Public Function ImageToBase64(ByVal image As Image, ByVal format As System.Drawing.Imaging.ImageFormat) As String
Dim base64String As String = ""
Using ms As New System.IO.MemoryStream()
image.Save(ms, format)
Dim imageBytes As Byte() = ms.ToArray()
base64String = Convert.ToBase64String(imageBytes)
End Using
Return base64String
End Function
So this:
Dim imagepathstring As String = System.IO.Path.Combine(folder & "\ArticlePics", imagepath)
Dim imgparameter As New ReportParameter
imgparameter = New ReportParameter("ImagePath", "file://" & imagepathstring, True)
.SetParameters(imgparameter)
Dim barpathstring As String = System.IO.Path.Combine(folder & "\BarCode", barpath)
Dim barcode As New ReportParameter("Barcode", "file://" & barpathstring, True)
.SetParameters(barcode)
will be like this:
Dim imagepathstring As String = System.IO.Path.Combine(folder & "\ArticlePics", imagepath)
Dim imgparameter As New ReportParameter
imgparameter = New ReportParameter("ImagePath", ImageToBase64(Image.FromFile(imagepathstring),<THE IMAGE FORMAT OF YOUR IMAGE>))
.SetParameters(imgparameter)
Dim barpathstring As String = System.IO.Path.Combine(folder & "\BarCode", barpath)
Dim barcode As New ReportParameter("Barcode", ImageToBase64(Image.FromFile(barpathstring),<THE IMAGE FORMAT OF YOUR IMAGE>))
.SetParameters(barcode)
Then, in your report set the following for:
ImagePath
MIMEType = select the correct MIME type from the dropdown list
Source = Database
Value = <Expression>
and in the Expression window:
=System.Convert.FromBase64String(Parameters!ImagePath.Value)
Barcode
MIMEType = select the correct MIME type from the dropdown list
Source = Database
Value = <Expression>
=System.Convert.FromBase64String(Parameters!Barcode.Value)

RDLC generate barcode using ZXing

I am pretty new to the RDLC report feature, I am looking to generate labels from Product data within a SQL database. When the user opens this Product/Part they are greeted with the information. When the user then clicks a button this will open the Report which will pass the parameters across to the Report in order to generate the label.
Dim myparam As ReportParameter
Dim testParameter As New List(Of ReportParameter)
myparam = New ReportParameter("PartID", "Test")
testParameter.Add(myparam)
myparam = New ReportParameter("MRPID", "Test MRP")
testParameter.Add(myparam)
myparam = New ReportParameter("PartName", "Test Name")
testParameter.Add(myparam)
ReportViewer1.LocalReport.SetParameters(testParameter)
Dim writer As New BarcodeWriter
writer.Format = BarcodeFormat.CODE_128
PictureBox1.Image = writer.Write(MRPID)
Me.ReportViewer1.RefreshReport()
As you can see, I am using XLing to generate my barcodes, which I have been successful in making work with the 3 lines of code you see above. However, I have no idea how I can pass this or have this generate on the report when ran. The barcode will be generated from the MRPID ie(TV001232). I understand this part is wrong "writer.Write(MRPID)" but I replaced the parameter value with MRPID so you could understand what I am trying to achieve.
Convert your image to Base64 string first using this:
Public Function ImageToBase64(ByVal image As Image, ByVal format As System.Drawing.Imaging.ImageFormat) As String
Dim base64String As String = ""
Using ms As New System.IO.MemoryStream()
image.Save(ms, format)
Dim imageBytes As Byte() = ms.ToArray()
base64String = Convert.ToBase64String(imageBytes)
End Using
Return base64String
End Function
So this:
myparam = New ReportParameter("MRPID", "Test MRP")
testParameter.Add(myparam)
Should be like this:
Dim writer As New BarcodeWriter
writer.Format = BarcodeFormat.CODE_128
myparam = New ReportParameter("MRPID", ImageToBase64(writer.Write(MRPID),<THE IMAGE FORMAT OF YOUR IMAGE>))
testParameter.Add(myparam)
Then, in your report set the following:
MIMEType = select the correct MIME type from the dropdown list
Source = Database
Value = <Expression>
and in the Expression window:
=System.Convert.FromBase64String(Parameters!MRPID.Value)

Searching Active Directory for Members of Specific Group Fails When User Has No Group

the following code is supposed to run through all users in active directory and find everyone in a specific group. Once it gets the users, it will add them to a datatable which will be the source of a gridview for a final export to Excel.
However, while running and stepping through, I've noticed it gets stopped on a certain user with no group. I tried adding a conditional statement to skip that instance, but it isn't working, the code still stops running when it finds the user with no group.
Can someone show me what I could be doing differently?
Caveat: This is from a legacy site that I inherited, knowing very little about active directory and being a novice vb coder.
Dim entry As DirectoryEntry = New DirectoryEntry("LDAP://DOMAIN.EDU", "USERNAME", "PASSWORD", AuthenticationTypes.Secure)
Dim search As DirectorySearcher = New DirectorySearcher(entry) With {
.Filter = "(&(objectCategory=User)(objectClass=person))",
.PageSize = 4000
}
search.PropertiesToLoad.Add("userPrincipalName").ToString
search.PropertiesToLoad.Add("name").ToString
Dim mySearchResultColl As SearchResultCollection = search.FindAll
Dim results As DataTable = New DataTable
results.Columns.Add("User ID")
results.Columns.Add("Full Name")
Dim CurrRow = 0
For Each sr As SearchResult In mySearchResultColl
Dim dr As DataRow = results.NewRow
Dim de As DirectoryEntry = sr.GetDirectoryEntry
!!!! line below is the problem !!!!
If de.Properties("memberOf") IsNot Nothing AndAlso de.Properties("memberOf").Value.ToString = "CN=MYGROUP,OU=Security Groups,OU=Students,DC=DOMAIN,DC=edu" Then
dr("User ID") = de.Properties("userPrincipalName").Value
dr("Full Name") = de.Properties("name").Value
results.Rows.Add(dr)
de.Close
End If
Next
gvNot.DataSource = results
gvNot.DataBind()
gvNot.Visible = True
gvAgreed.Visible = False
ExportToExcel("notagreed", gvNot)
I'm not sure what you mean by "gets stopped", but you can change this up so it performs better and fixes any issues you have.
This loop will take forever since you have to inspect every user on the domain. If you only want users in a specific group, then you can speed this up by only asking for members of the group. You do that by adding a condition in the query for the memberOf attribute. This way, you only get results you care about.
(Note that if you have more than one domain in your forest, using memberOf to find members may not work the way you want. I wrote about that here. But if you only have one domain, then it'll be fine.)
In the loop, don't create a DirectoryEntry for each result, since that will force it to go back out to AD and request the attributes for the object again, even though you already got what you needed in the search results. So use the values in the SearchResult object instead.
The documentation for SearchResultCollection says:
Due to implementation restrictions, the SearchResultCollection class cannot release all of its unmanaged resources when it is garbage collected. To prevent a memory leak, you must call the Dispose method when the SearchResultCollection object is no longer needed.
So you should put that in a Using clause.
I'm also not sure why you're calling ToString on PropertiesToLoad.Add when you're not using the return value. You can just remove that.
Here it is all together:
Dim entry As DirectoryEntry = New DirectoryEntry("LDAP://DOMAIN.EDU", "USERNAME", "PASSWORD", AuthenticationTypes.Secure)
Dim search As DirectorySearcher = New DirectorySearcher(entry) With {
.Filter = "(&(objectCategory=User)(objectClass=person)(memberOf=CN=MYGROUP,OU=Security Groups,OU=Students,DC=DOMAIN,DC=edu))",
.PageSize = 4000
}
search.PropertiesToLoad.Add("userPrincipalName")
search.PropertiesToLoad.Add("name")
Dim results As DataTable = New DataTable
results.Columns.Add("User ID")
results.Columns.Add("Full Name")
Dim CurrRow = 0
Using mySearchResultColl As SearchResultCollection = search.FindAll
For Each sr As SearchResult In mySearchResultColl
Dim dr As DataRow = results.NewRow
dr("User ID") = sr.Properties("userPrincipalName")(0)
dr("Full Name") = sr.Properties("name")(0)
results.Rows.Add(dr)
Next
End Using
gvNot.DataSource = results
gvNot.DataBind()
gvNot.Visible = True
gvAgreed.Visible = False
ExportToExcel("notagreed", gvNot)
I don't see you using CurrRow anywhere, but I left it in case you're using it in other code you didn't show here.
Try using String.Equals function with StringComparer.OrdinalIgnoreCase parameter instead of using equals operator.
Also what's the error you are getting?

LINQ Query Causing Exit Sub or Swallowing Error

My code is as follows:
Using _EntityModel As New AboveNemaSalesDatabaseEntities()
Dim _SelectActiveOptionCodes = (From _OptCodes In _EntityModel.tblOptionCodes
Where _OptCodes.fdStatus = "A"
Select _OptCodes.fdDescription, _OptCodes.fdOptionCode).ToList()
Dim _SelectActiveOptionCodes2 = (From _OptCodes In _EntityModel.tblOptionCodes
Where _OptCodes.fdStatus = "A"
Select New optionCodes With {.description = _OptCodes.fdDescription,
.optionCode = _OptCodes.fdOptionCode})
sortableOptionCodes = _SelectActiveOptionCodes2
sortedOptionCodes = _SelectActiveOptionCodes2
OptionCodeListBox.DataSource = sortedOptionCodes
OptionCodeListBox.DisplayMember = "fdDescription"
OptionCodeListBox.ValueMember = "fdOptionCode"
End Using
The first query works fine and returns a list in the format [index]{description = "descritption here", optionCode = "option code here"}
The second query creates but when it is called to save to my custom class the program exits the sub or swallows an error. Stepping through the code, the line starting with sortedOptionCodes and after never runs.
The main issue I was dealing with is that my query was producing a list of optionCodes and my variable was not prepared to store this.
Old variables:
Dim sortableOptionCodes As optionCodes
Dim sortedOptionCodes As optionCodes
New variables:
Dim sortableOptionCodes As List(Of optionCodes)
Dim sortedOptionCodes As List(Of optionCodes)
I also added a .ToList() function to the end of the second query.