why RDLC Report Show #ERROR when printing? - vb.net

i have a problem that has been bothering me for more than three weeks. i have searched for the solution in several forums, but without success. i am creating a small application with windows form using .net framwork 4.7.2. and RDLC report.
my problem is the following:
I have created an RDLC report and it takes a costomized code that works apparently well. but when I launch the print I have this message #ERROR. for that to come back to normal, I have to refresh and it's disturbing.
please help me with any suggestion.
Good File
as you can see in the picture above, the report is working
when i export or preview, this is what happens as shown in the image below
Bad File
here is the costomized code that I use in my report code.
<pre>Function SumLookup(ByVal items As Object()) As Decimal
If items Is Nothing Then
Return Nothing
End If
Dim suma As Decimal = New Decimal()
Dim ct as Integer = New Integer()
suma = 0
ct = 0
For Each item As Object In items
suma += Convert.ToDecimal(item)
ct += 1
Next
If (ct = 0) Then return 0 else return suma
End Function
</pre>
the expression of my textbox
=Round(cdbl(Code.SumLookup(LookupSet(Fields!Matiere.value, Fields!Matiere.value, Fields!NoteEleve.Value*Fields!Coef.Value, "Bulletin"))),2)
please help me. I don't know what to do.
I tried this function in the code area of the report
<pre>Function SumLookup(ByVal items As Object()) As Decimal
If items Is Nothing Then
Return Nothing
End If
Dim suma As Decimal = New Decimal()
Dim ct as Integer = New Integer()
suma = 0
ct = 0
For Each item As Object In items
suma += Convert.ToDecimal(item)
ct += 1
Next
If (ct = 0) Then return 0 else return suma
End Function
</pre>
and this one in the textbox
=Round(cdbl(Code.SumLookup(LookupSet(Fields!Matiere.value, Fields!Matiere.value, Fields!NoteEleve.Value*Fields!Coef.Value, "Bulletin"))),2)

Related

How to get a certain code for an equation

I'm a beginner working on my first application using Visual Basic in Visual Studio 2019.
I want to calculate this:
I have all Wi in (list view) and also (text box).
I have all Hi in (list view).
My problem is how could I multiply wi list view (or Wi text box) by hi list view and get this result in a third list view ?
I expect that the biggest problem you have found is getting the data from the ListViews - please note that using a Control to store data is usually a bad idea.
Note that array indexes in VB.NET (and C# and many other computer languages) start at zero (i.e. they are offsets, rather than indices as used in maths).
Once you have the data in arrays, it is easy to perform the calculation. Coming up with meaningful names for the methods and variables is also a problem.
With ListViews named ListViewW, ListViewH, and ListViewF I came up with this:
Public Class Form1
Dim rand As New Random()
Function Fvalues(Fb As Double, weights As Double(), values As Double()) As Double()
If weights.Length <> values.Length Then
Throw New ArgumentException("Number of weights does not equal number of values.")
End If
'TODO: Possibly more argument checking.
Dim total = 0.0
For i = 0 To weights.Length - 1
total += weights(i) * values(i)
Next
'TODO: Check for total = 0.
Dim F(weights.Length - 1) As Double
For i = 0 To weights.Length - 1
F(i) = Fb * weights(i) * values(i) / total
Next
Return F
End Function
Function ListViewToDoubles(lv As ListView) As Double()
Dim d As New List(Of Double)
For i = 0 To lv.Items.Count - 1
Dim dbl As Double
If Double.TryParse(lv.Items(i).Text, dbl) Then
d.Add(dbl)
End If
Next
Return d.ToArray()
End Function
Sub CreateSampleData()
For i = 1 To 5
ListViewW.Items.Add(rand.NextDouble().ToString())
ListViewH.Items.Add(rand.Next(0, 11).ToString())
Next
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
CreateSampleData()
Dim weights = ListViewToDoubles(ListViewW)
Dim values = ListViewToDoubles(ListViewH)
Dim f = Fvalues(0.5, weights, values)
For Each x In f
ListViewF.Items.Add(x.ToString())
Next
End Sub
End Class

VB.NET Lambda expression in contextmenu getting wrong item

I'd be grateful if anybody could shed some light on a problem.
I have a form showing a sales order, this has a DGV (DGVDocs) showing a list of invoices against that order. I've populated a print button with the documents and for each a submenu with Print, Preview, PDF. The lambda expressions on the submenu always pick up the last entry on the menu.
Private Sub create_print_menu()
Dim i As Integer = 0
ms = New ContextMenuStrip
If dgvDocs.Rows.Count > 0 Then
Dim doctype As String = ""
Dim docno As Integer = 0
For i = 0 To dgvDocs.Rows.Count - 1
ms.Items.Add(RTrim(dgvDocs.Rows(i).Cells(0).Value) & " " & RTrim(dgvDocs.Rows(i).Cells(2).Value))
jc = ms.Items(ms.Items.Count - 1)
doctype = RTrim(dgvDocs.Rows(i).Cells(0).Value)
docno = RTrim(dgvDocs.Rows(i).Cells(2).Value)
jc.DropDownItems.Add("Preview", Nothing, Function(sender, e) docPreview(doctype, docno))
Next
End If
End Sub
Private Function docPreview(ByVal doctype As String, ByVal docno As Integer)
If doctype.ToUpper.Contains("DESPATCH NOTE") Then
Dim frm As New frmDespatchPreview
frm.delnote = docno
frm.ShowDialog()
ElseIf doctype.ToUpper.Contains("INVOICE") Then
Dim frm As New frmInvoicePreview
frm.invno = docno
frm.ShowDialog()
End If
Return True
Return True
End Function
when you pass the lambda in your loop:
Function(sender, e) docPreview(doctype, docno)
... you are not passing in a copy or snapshot of whatever value is in doctype and docno at the time of that specific loop iteration. You are actually passing in a reference to those variables.
So, by the end of the loop, all the lambdas will effectively have a reference to whatever the last value of doctype and docno is.
To avoid this problem, make sure each lambda refers to a different variable reference. This can be accomplished by declaring doctype and docno inside the loop, like this:
'Dim doctype As String = ""
'Dim docno As Integer = 0
For i = 0 To dgvDocs.Rows.Count - 1
ms.Items.Add(RTrim(dgvDocs.Rows(i).Cells(0).Value) & " " & RTrim(dgvDocs.Rows(i).Cells(2).Value))
jc = ms.Items(ms.Items.Count - 1)
Dim doctype As String = RTrim(dgvDocs.Rows(i).Cells(0).Value)
Dim docno As Integer = RTrim(dgvDocs.Rows(i).Cells(2).Value)
jc.DropDownItems.Add("Preview", Nothing, Function(sender, e) docPreview(doctype, docno))
Next
EDIT:
Relevant article: Closures in VB Part 5: Looping

How to populate ObjectListView using Dataset

Can someone please tell me what I'm doing wrong....
I am trying to populate an ObjectListView control by looping through a dataset (I don't want to bind it to my dataset). The first row populates but nothing after that.
My code looks like so:
If dsOverdueCalls.Tables.Count > 0 And dsOverdueCalls.Tables(0).Rows.Count > 0 Then
For x = 0 To (dsOverdueCalls.Tables(0).Rows.Count - 1)
'Calculate overdue amount
.....
Dim lstCalls = New List(Of [Call_Details])() From {New [Call_Details]() With {.Id = tempDT.Rows(x)("id").ToString, .Summary = tempDT.Rows(x)("summary").ToString, .First_Name = tempDT.Rows(x)("first_name").ToString, .Due_At = OverdueStr}}
lsvOverdueCalls.SetObjects(lstCalls)
Next
End If
I get no errors but only the first record will populate in my control.
Thanks
You're resetting the ObjectListView in each iteration. So, what you believe is the "first" row is actually the last row. The following code will fix your issue.
If ((dsOverdueCalls.Tables.Count > 0) AndAlso (dsOverdueCalls.Tables(0).Rows.Count > 0)) Then
Dim lstCalls = New List(Of [Call_Details])
For x As Integer = 0 To (dsOverdueCalls.Tables(0).Rows.Count - 1)
lstCalls.Add(New [Call_Details]() With {.Id = tempDT.Rows(x)("id").ToString, .Summary = tempDT.Rows(x)("summary").ToString, .First_Name = tempDT.Rows(x)("first_name").ToString, .Due_At = OverdueStr})
Next
lsvOverdueCalls.SetObjects(lstCalls)
End If

How to get each value in an array and show it in a listbox

Hi I am new to VB and I have problems with using array. My code is like that.
This is class FindFactorsObject.vb
Public Sub FindFactors()
count = 0
temp = Convert.ToInt32(Math.Sqrt(_x))
For i As Integer = 1 To temp
If _x Mod i = 0 Then
ReDim array(count)
array(count) = i
count += 1
End If
Next
So I created an array and stored the results. Now I want to display each value in my array in Form.vb and if it is possible can somebody teach me how to make delay for each of the displayed value. Thanks very much
Always declare your variables, if possible to their exact types, you think they will take care of. When you say 'Now I want to display each value in my array in Form.vb' I understood literally: in the Form so, we will print them on your form
Public Sub FindFactors(_x As Integer)
Dim temp As Integer = Convert.ToInt32(Math.Sqrt(_x))
Dim l As New List(Of Integer)
For i As Integer = 1 To temp
If _x Mod i = 0 Then
l.add(i)
End If
Next
Dim pf As New PointF(20, 20)
For Each i As Integer In l
creategraphics.drawstring(i.ToString, New font(font.fontFamily, 24), brushes.cadetblue, pf)
pf = New PointF(pf.X, pf.Y + 30)
Next
End Sub

How can I calculate the number of lines in a text box?

I am hoping that someone can help me with a problem I've got at the moment using Compact Framework.Net 2 SP 2.
At the moment I have a UI with a series of text boxes and each textbox displays the contents of a database field. These are shown one beneath another with a scroll bar on the right hand side of the form. Each textbox has a set width which might
I would like to adjust the height each text box based on the number of lines it is holding, the font size and the font in order to avoid using scroll bars on each textbox.
At the moment I am been able to do this in a test application.
Screenshot:
see screenshot for output http://morrislgn.brinkster.net/SO/screenshot.jpg
My code:
'Text used in this example:
'TextBox1qwertyuiop lkjhgfdsazxcvbnm1234567890 TextBo
'x1qwer tyuioplkjhgfdsazxcvb nm1234567890
'qwe
'End of exmaple text.
Me.Textbox2.Text = Me.Textbox1.Text
Dim pobjGraphic As Graphics = Me.Textbox2.Parent.CreateGraphics()
Dim pobjSize As SizeF
'Padding values:
Dim piTop As Int32 = 4 'top of text and top of textbox
Dim piBottom As Int32 = 3 'bottom of text and top of textbox
Dim piLines As Int32 = 0
'Based on the font size chosen by the user, create a font to perform the calculation with.
Dim piFontSize As Single = 10
If Me.CheckBox1.Checked.Equals(True) Then
piFontSize = 6
ElseIf Me.CheckBox2.Checked.Equals(True) Then
piFontSize = 8
ElseIf Me.CheckBox3.Checked.Equals(True) Then
piFontSize = 12
Else
piFontSize = 10
End If
Dim pobjFont As New Font("Tahoma", piFontSize, FontStyle.Regular)
'Calculate the height of one line.
pobjSize = pobjGraphic.MeasureString("HELLO WORLD", pobjFont)
'Value of pobjSize returned: {Width = 71.0 Height = 13.0}
'Calculate the number of lines
Dim b As Bitmap
b = New Bitmap(1, 1, Imaging.PixelFormat.Format32bppRgb)
'Calculate the number of lines required to display the text properly based on the lenght of the text the width of the control.
'Length of text to show divide by the width of the textbox
piLines = Graphics.FromImage(b).MeasureString(Me.Textbox2.Text, pobjFont).Width / Me.Textbox2.Width
'Value of piLines returned: 2
If piLines = 0 Then
piLines = 1
End If
'Calculate the size of the text to be displayed using the margins, height of one line and number of lines.
Me.Textbox2.Height = (pobjSize.Height * piLines) + piTop + piBottom
' value produced: 33 = (13 * 2) + 4 + 3
'set font of text box
Me.Textbox2.Font = pobjFont
Finally, I know this can be achieved using a call to the COREDLL.dll using p/invoke but doing this makes the application crash.
Hi Folks,
Below is the pinvoke code as requested:
<Runtime.InteropServices.DllImport("coredll.dll")> _
Private Function SendMessage( _
ByVal hwnd As IntPtr, ByVal msg As Integer, _
ByVal wParam As Integer, ByVal lParam As Integer) As Integer
End Function
<Runtime.InteropServices.DllImport("coredll.dll")> _
Private Function GetCapture() As IntPtr
End Function
<Runtime.InteropServices.DllImport("coredll.dll")> _
Private Function ReleaseCapture() As Boolean
End Function
Public Function GetNumberOfLines(ByVal ptxtCountBox As TextBox) As Integer
Try
Dim hnd As IntPtr = New IntPtr
ptxtCountBox.Capture = True
' Capture the textbox handle.
hnd = GetCapture()
ptxtCountBox.Capture = False
' Get the count of the lines in the box.
Dim plCount As Integer = SendMessage(ptxtCountBox.Handle, EM_GETLINECOUNT, 0, 0)
' Count the number of return lines as we minus this from the total lines to take.
plCount = plCount - (CharCount(ptxtCountBox.Text, vbCrLf, False))
plCount += RemoveNonASCIIReturns(ptxtCountBox)
ReleaseCapture()
hnd = Nothing
' Return the line count.
Return plCount
Catch ex As Exception
GenerateError(msCLASS_NAME, "GetNumberOfLines", ex.Message.ToString)
End Try
End Function
Thanks,
Morris
I asked a similar question and got an answer that completely satisfied my needs on the subject! Please check out stevo3000's answer from my question:
AutoSize for Label / TextBox in .NET Compact Framework
He referred to these two blog posts that just completely fixed my problem with one swipe!
http://www.mobilepractices.com/2007/12/multi-line-graphicsmeasurestring.html
http://www.mobilepractices.com/2008/01/making-multiline-measurestring-work.html
Think I got to the bottom of this:
Public Function GetNumberOfLines(ByVal pstext As String, ByVal pobjfont As Font, ByVal pobjDimensions As Size) As Decimal
Dim pslines As String() = Nothing
'Used to measure the string to be placed into the textbox
Dim pobjBitMap As Bitmap = Nothing
Dim pobjSize As SizeF = Nothing
Try
Dim psline As String = String.Empty
Dim pilinecount As Decimal = 0.0
'Spilt the text based on the number of lines breaks.
pslines = pstext.Split(vbCrLf)
For Each psline In pslines
'Create a graphics image which is used to work out the width of the text.
pobjBitMap = New Bitmap(1, 1, Imaging.PixelFormat.Format32bppRgb)
pobjSize = Graphics.FromImage(pobjBitMap).MeasureString(psline, pobjfont)
'If the width of the text is less than 1.0 then add one to the count. This would incidcate a line break.
If pobjSize.Width < 1.0 Then
pilinecount = pilinecount + 1
Else
'Based on the dimensions of the text, work out the number of lines. 0.5 is added to round the value to next whole number.
pilinecount = pilinecount + (Round((pobjSize.Width / pobjDimensions.Width) + 0.5))
End If
Next
'If the line count it less than 1 return one line.
If pilinecount < 1.0 Then
Return 1.0
Else
Return pilinecount
End If
Catch ex As Exception
Return 1.0
Finally
If pslines IsNot Nothing Then
Array.Clear(pslines, 0, pslines.Length - 1)
pslines = Nothing
End If
If pobjBitMap IsNot Nothing Then
pobjBitMap.Dispose()
End If
End Try
End Function
Granted, its a bit of a hack but it appears to work ok at the moment! Any observations or comments on how to improve this are more than welcome.
Also, about the p/invoke stuff, discovered the root of the problem, or rather the solution. Upgraded the .Net fx on my device and that appears to have resolved the issue.
Thanks
Morris
Well, I would suggest a sound and smart solution to you.
Here's is the Algorithm:
Use a Label control for reference.
Assign:
• The size of Textbox to the Label.
• The font of Textbox to the Label.
• Autosize-property of Label to be True.
• BorderStyle Property of the Label as of Textbox'.
• MinimumSize Property of Label as original size of the Textbox.
• MaximumSize Property of Label as Width-same as original and Height to be a large multiple the original height.
Assign the Textbox' Text to Label's text.
Now: if the PrefferdHeight-property of Label > Height of the Textbox == True
It's time to increase the height of the Textbox and check the above condition until it’s False.
The Label can be disposed off now.
I have also posted a similar solution in MSDN Forum which can also be checked out:
[http://social.msdn.microsoft.com/Forums/en-US/winforms/thread/03fc8e75-fc13-417a-ad8c-d2b26a3a4dda][1]
Regards.
:)