Error after I inserted custom code in SSRS - sql

After I inserted custom code in my SSRS report I got this error:
An error occurred during local report processing. The definition of the report ...in invalid. An unexpected error occured while compiling expressions. Native compiler return valid '[BC42105]' Function 'ColorDWB' doesn't return a value on all code paths. A null reference exception could occur at a run time when the result is used.
All I am trying to do is create a Excel like heat map based on shades of colors.
My custom code:
Public Shared Function ColorDWB(ByVal Value As Decimal, ByVal MaxPositive As Decimal,
ByVal Neutral As Decimal, ByVal ColStr As String) As String
Dim ColVar1 As Integer Dim ColVar2
As Integer Dim ColVar3 As Integer ‘Split the #RGB color to R, G, and B components
ColVar1=Convert.ToInt32(left(right(ColStr, 6),2),16)
ColVar2=Convert.ToInt32(left(right(ColStr, 4),2),16)
ColVar3=Convert.ToInt32(right(ColStr, 2),16) ‘Find Largest Range Dim decPosRange
As Decimal = Math.Abs(MaxPositive – Neutral) ‘Find appropriate color shade
Dim Shd As Decimal = 255
Dim iColor1 As Integer
Dim iColor2 As Integer
Dim iColor3 As Integer
Dim strColor As String ‘Reduce a shade for each of the R,G,B components
iColor1 = ColVar1 + CInt(Math.Round((MaxPositive-Value) * ((Shd – ColVar1) / decPosRange)))
iColor2 = ColVar2 + CInt(Math.Round((MaxPositive-Value) * ((Shd – ColVar2) / decPosRange)))
iColor3 = ColVar3 + CInt(Math.Round((MaxPositive-Value) * ((Shd – ColVar3) / decPosRange)))
strColor = “#” & iColor1.ToString(“X2”) & iColor2.ToString(“X2”) & iColor3.ToString(“X2”)
Return strColor
End Function
And its not a first code that gives me the same error. I dont know much about VB. What am I missing here?

I've corrected and tested your function:
Public Shared Function ColorDWB(ByVal Value As Decimal, ByVal MaxPositive As Decimal, ByVal Neutral As Decimal, ByVal ColStr As String) As String
Dim ColVar1 As Integer
Dim ColVar2 As Integer
Dim ColVar3 As Integer
'Split the #RGB color to R, G, and B components
ColVar1 = Convert.ToInt32(left(right(ColStr, 6), 2), 16)
ColVar2 = Convert.ToInt32(left(right(ColStr, 4), 2), 16)
ColVar3 = Convert.ToInt32(right(ColStr, 2), 16)
'Find Largest Range
Dim decPosRange As Decimal = Math.Abs(MaxPositive - Neutral)
'Find appropriate color shade
Dim Shd As Decimal = 255
Dim iColor1 As Integer
Dim iColor2 As Integer
Dim iColor3 As Integer
Dim strColor As String
'Reduce a shade for each of the R,G,B components
iColor1 = ColVar1 + CInt(Math.Round((MaxPositive - Value) * ((Shd - ColVar1) / decPosRange)))
iColor2 = ColVar2 + CInt(Math.Round((MaxPositive - Value) * ((Shd - ColVar2) / decPosRange)))
iColor3 = ColVar3 + CInt(Math.Round((MaxPositive - Value) * ((Shd - ColVar3) / decPosRange)))
'Return the new color
strColor = "#" & iColor1.ToString("X2") & iColor2.ToString("X2") & iColor3.ToString("X2")
Return strColor
End Function
Maybe you need to do some fixes, but it works.
Here is a fiddle: https://dotnetfiddle.net/g3nR0O

Related

Using Logo to draw sound

I'm using Logo right now and i'm making a project and basically i want to turn your recorded voice into something visual, only problem is when i go to find code it re that works it requires 1: A picture box and 2: to manually grab the sound .wav file and place it. I already made code to record my voice and to make it into a .Wav file and i already have code to visualize it, just when i run it it appears as a thick square of lines rather than the example i shown. Note: I'm not drawing into a picturebox, i'm drawing directly into the Form by using g.drawline(bleh,bleh,bleh,bleh).
(Example: http://static1.1.sqspcdn.com/static/f/335152/16812948/1330286658510/76_dsc3616.jpeg?token=R1zPNnr9PAoB3WvnDxfFFFvzkMw%3D )
The code im trying to run:
Public Sub DrawSound(x As Integer, y As Integer)
Dim samplez As New List(Of Short)
Dim maxamount As Short
Dim pic As New Bitmap(x, y)
Dim ratio As Integer = (samplez.Count - 1) / (y - 1) 'If there are 10000 samples and 200 pixels, this would be every 50th sample is shown
Dim halfpic As Integer = (x / 2) 'Simply half the height of the picturebox
GC.Collect()
Dim wavefile() As Byte = IO.File.ReadAllBytes("C:\Users\" & Environ$("Username") & "\Documents\Sounds\Mic.wav")
GC.Collect()
Dim memstream As New IO.MemoryStream(wavefile)
Dim binreader As New IO.BinaryReader(memstream)
Dim ChunkID As Integer = binreader.ReadInt32()
Dim filesize As Integer = binreader.ReadInt32()
Dim rifftype As Integer = binreader.ReadInt32()
Dim fmtID As Integer = binreader.ReadInt32()
Dim fmtsize As Integer = binreader.ReadInt32()
Dim fmtcode As Integer = binreader.ReadInt16()
Dim channels As Integer = binreader.ReadInt16()
Dim samplerate As Integer = binreader.ReadInt32()
Dim fmtAvgBPS As Integer = binreader.ReadInt32()
Dim fmtblockalign As Integer = binreader.ReadInt16()
Dim bitdepth As Integer = binreader.ReadInt16()
If fmtsize = 18 Then
Dim fmtextrasize As Integer = binreader.ReadInt16()
binreader.ReadBytes(fmtextrasize)
End If
Dim DataID As Integer = binreader.ReadInt32()
Dim DataSize As Integer = binreader.ReadInt32()
samplez.Clear()
For i = 0 To (DataSize - 3) / 2
samplez.Add(binreader.ReadInt16())
If samplez(samplez.Count - 1) > maxamount Then 'Using this for the pic
maxamount = samplez(samplez.Count - 1)
End If
Next
For i = 1 To x - 10 Step 2 'Steping 2 because in one go, we do 2 samples
Dim leftdata As Integer = Math.Abs(samplez(i * ratio)) 'Grabbing that N-th sample to display. Using Absolute to show them one direction
Dim leftpercent As Single = leftdata / (maxamount * 2) 'This breaks it down to something like 0.0 to 1.0. Multiplying by 2 to make it half.
Dim leftpicheight As Integer = leftpercent * x 'So when the percent is tied to the height, its only a percent of the height
g.DrawLine(Pens.LimeGreen, i, halfpic, i, leftpicheight + halfpic) 'Draw dat! The half pic puts it in the center
Dim rightdata As Integer = Math.Abs(samplez((i + 1) * ratio)) 'Same thing except we're grabbing i + 1 because we'd skip it because of the 'step 2' on the for statement
Dim rightpercent As Single = -rightdata / (maxamount * 2) 'put a negative infront of data so it goes down.
Dim rightpicheight As Integer = rightpercent * x
g.DrawLine(Pens.Blue, i, halfpic, i, rightpicheight + halfpic)
Next
End Sub
X and Y is the middle of the form. And i also would link where i got the code but i forgot where and also, i modified it in attempt to run it directly into he form rather than a picturebox. It worked sorta haha (And there is so many unused dims but all i know is, once i remove one none of the code works haha) So could anyone help?

Using individual value from multiple values returned by a function VB.net

I have a function which returns average RGB value of a region drawn on a picturebox in VB.net.
The code is as below:
Function GetAvgRGB(ByVal CrdY As Integer, ByVal CrdX As Integer, ByVal Region As System.Drawing.Rectangle) As Tuple(Of Integer, Integer, Integer)
Dim totalR As UInteger
Dim totalG As UInteger
Dim totalB As UInteger
For y As Integer = CrdY - (Region.Height / 2) To CrdY + ((Region.Height / 2) - 1)
For x As Integer = CrdX - (Region.Width / 2) To CrdX + ((Region.Width / 2) - 1)
totalR += myBitmap.GetPixel(x, y).R
totalG += myBitmap.GetPixel(x, y).G
totalB += myBitmap.GetPixel(x, y).B
Next
Next
Dim pixelCount As Integer = Region.Width * Region.Height
Dim averageR As Integer = CType(totalR \ pixelCount, Integer)
Dim averageG As Integer = CType(totalG \ pixelCount, Integer)
Dim averageB As Integer = CType(totalB \ pixelCount, Integer)
Return Tuple.Create(averageR, averageG, averageB)
End Function
My query is how do I separate the values of R, G & B returned by this function..
Use the Item property.
Dim myTuple = GetAvgRGB(?,?,?)
Dim r = myTuple.Item1 ' g = .Item2, b = .Item3

SSRS Report Builder 3.0: Conditional Formatting Gradient Color

I can find plenty of tutorials on how to use conditional formatting of tablix fields in Report Builder 3.0. However I would like a function that creates a gradient color, from black to red, which colors the text more and more red, the closer it comes to a certain number.
For example I got a column with the age of a product component in days. I want the text to be black (#000000), when the component is 0 days old. And then gradually turn into red, hitting a pure red (#FF0000) on the day it expires (could be day 30).
Can anyone provide me any information, regarding how to do that?
I ended up modifying the function from the solution linked by Alejandro.
Public Shared Function ColorDWB(ByVal Value As Decimal, ByVal MaxPositive As Decimal, ByVal Neutral As Decimal, ByVal ColStr As String) As String
'Initiate variables for Red, Green and Blue (RGB)
Dim ColVar1 As Integer
Dim ColVar2 As Integer
Dim ColVar3 As Integer
'Split the #RGB color to R, G, and B components
ColVar1=Convert.ToInt32(left(right(ColStr, 6),2),16)
ColVar2=Convert.ToInt32(left(right(ColStr, 4),2),16)
ColVar3=Convert.ToInt32(right(ColStr, 2),16)
'Find Largest Range
Dim decPosRange As Decimal = Math.Abs(MaxPositive - Neutral)
Dim iColor1 As Integer
Dim iColor2 As Integer
Dim iColor3 As Integer
Dim strColor As String
'Reduce a shade for each of the R,G,B components
iColor1 = Math.Max(0, Math.Min(ColVar1, ColVar1*(Value-Neutral)/(MaxPositive-Neutral)))
iColor2 = Math.Max(0, Math.Min(ColVar2, ColVar2*(Value-Neutral)/(MaxPositive-Neutral)))
iColor3 = Math.Max(0, Math.Min(ColVar3, ColVar3*(Value-Neutral)/(MaxPositive-Neutral)))
'Return the new color
strColor = "#" & iColor1.ToString("X2") & iColor2.ToString("X2") & iColor3.ToString("X2")
Return strColor
End Function
Like the answer before me, that article got me started but I modified to make it work better for my purposes.
Public Function HeatMap(ByVal Value As Double _
, ByVal MinVal As Double _
, ByVal MaxVal As Double _
, ByVal RValLo As Double _
, ByVal GValLo As Double _
, ByVal BValLo As Double _
, ByVal RValHi As Double _
, ByVal GValHi As Double _
, ByVal BValHi As Double _
) As String
Dim DiffPercent As Double
Dim RNew As Integer
Dim GNew As Integer
Dim BNew As Integer
Dim HeatMapColor As String
If Value = Nothing Then
RNew = 255
GNew = 255
BNew = 255
ElseIf Value <= MinVal Then
RNew = RValLo
GNew = GValLo
BNew = BValLo
ElseIf Value >= MaxVal Then
RNew = RValHi
GNew = GValHi
BNew = BValHi
Else
DiffPercent = (Value - MinVal) / (MaxVal - MinVal)
RNew = RValLo - Round((RValLo - RValHi) * DiffPercent, 0)
GNew = GValLo - Round((GValLo - GValHi) * DiffPercent, 0)
BNew = BValLo - Round((BValLo - BValHi) * DiffPercent, 0)
End If
HeatMapColor = "#" & Hex(RNew) & Hex(GNew) & Hex(BNew)
HeatMap = HeatMapColor
End Function
More info on my approach here: How to create heat map on a table in SSRS?

extract substring in vb.net

I have following string, and would need to extract the X and Y values cut to a single digit after the point.
A234X78.027Y141.864D1234.2
There are a few variables that can change here:
the string can have any length and contain any number of values
I know that X and Y are Always present, but they do not have to be in a specific order in the string
Each value for X or Y can have any lenght.. for example x can be 1.1 or 1234.1
it is not imperative that X or Y do have a point. it can also be a round number, for example X78Y141.34561 (note that X has no point) If there is no point I am ok with the value, but if there is a point then I would need the first digit after the point. (rounded)
As a Result of the above string I would need two string variables containing the values 78.0 and 141.9
EDIT: Updated the last sentence, the variables should contain JUST the value, no X and Y. Sorry for the mistake
Update, code as requested
Dim objReader As New System.IO.StreamReader(FILE_NAME)
Do While objReader.Peek() <> -1
Dim curline As String = objReader.ReadLine() 'curline = G1X39.594Y234.826F1800.0
If curline.Contains("X") Then
Dim t As String = ExtractPoint(curline, "X"c) 't = "39.594"
Dim d As Double = Math.Round(Convert.ToDouble(t), 1) 'd= 39594.0
destx = d * 10 'destx = 395940
End If
Loop
Function ExtractPoint(dataString As String, character As Char) As String
Dim substring As String = String.Empty
Dim xIndex As Integer = dataString.IndexOf(character) + 1
substring += dataString(xIndex)
xIndex = xIndex + 1
While (xIndex < dataString.Length AndAlso Char.IsLetter(dataString(xIndex)) = False)
substring += dataString(xIndex)
xIndex = xIndex + 1
End While
Return substring
End Function
Your sample data indicates that fields are separated by letters, and the last letter ends with the string. Knowing that you can parse your desired letters out manually and round to 1 decimal point.
This also takes into account when there is no decimal point, but it will display a .0 at the end of the number.
EDIT
Moved common code to a function
Update
Doesn't include the letter as part of the output
Sub Main()
Dim dataString As String = "G1X39.594Y234.826F1800.0"
Dim xString As String = ExtractPoint(dataString, "X"c)
Dim yString As String = ExtractPoint(dataString, "Y"c)
Dim xDouble As Double = Math.Round(Convert.ToDouble(xString), 1)
Dim yDouble As Double = Math.Round(Convert.ToDouble(yString), 1)
Console.WriteLine(xDouble.ToString("F1"))
Console.WriteLine(yDouble.ToString("F1"))
Console.WriteLine((xDouble * 10).ToString("F1"))
Console.WriteLine((yDouble * 10).ToString("F1"))
Console.ReadLine()
End Sub
Function ExtractPoint(dataString As String, character As Char) As String
Dim substring As String = String.Empty
Dim xIndex As Integer = dataString.IndexOf(character) + 1
substring += dataString(xIndex)
xIndex = xIndex + 1
While (xIndex < dataString.Length AndAlso Char.IsLetter(dataString(xIndex)) = False)
substring += dataString(xIndex)
xIndex = xIndex + 1
End While
Return substring
End Function
Results:
Have you looked into Regular Expressions?
Dim x As System.Text.RegularExpressions.Match = System.Text.RegularExpressions.Regex.Match(TextBox1.Text, "X\d+([.]\d{1})?")
Dim y As System.Text.RegularExpressions.Match = System.Text.RegularExpressions.Regex.Match(TextBox1.Text, "Y\d+([.]\d{1})?")
MsgBox(x.ToString & " -- " & y.ToString)
I believe this will do what you are looking for if I understood correctly.
EDIT For Only getting the numbers after X and Y
Based off my original code, you could do something like this.
This also rounds the numbers to the nearest one decimal place.
Dim x As System.Text.RegularExpressions.Match = System.Text.RegularExpressions.Regex.Match(TextBox1.Text, "X(\d+([.]\d{2})?)")
Dim y As System.Text.RegularExpressions.Match = System.Text.RegularExpressions.Regex.Match(TextBox1.Text, "Y(\d+([.]\d{2})?)")
MsgBox(Math.Round(CDbl(x.Groups(1).Value), 1) & " -- " & Math.Round(CDbl(y.Groups(1).Value), 1))
Updated code for added code
Dim s As String = "A234X78.027Y141.864D1234.2"
Dim dX As Double = Extract(s, "X")
Dim dY As Double = Extract(s, "Y")
MsgBox(dX * 10 & "-" & dY * 10)
Private Function Extract(ByRef a As String, ByRef l As String) As Double
Dim x As System.Text.RegularExpressions.Match = System.Text.RegularExpressions.Regex.Match(a, l & "(\d+([.]\d{2})?)")
Return Math.Round(CDbl(x.Groups(1).Value), 1)
End Function
Here is a simple LINQ function that should do it for you (no regex, no long code):
Private Function ExtractX(s As String, symbol As Char) As String
Dim XPos = s.IndexOf(symbol)
Dim s1 = s.Substring(XPos + 1).TakeWhile(Function(c) Char.IsDigit(c)).ToArray()
If (XPos + 1 + s1.Length < s.Length) AndAlso s.Substring(XPos + 1 + s1.Length)(0) = "."c AndAlso Char.IsDigit(s.Substring(XPos + 1 + s1.Length)(1)) Then
Return String.Join("", s1, s.Substring(XPos + 1 + s1.Length, 2))
Else
Return s1
End If
End Function
Call it like this:
Dim s = "A234X78.027Y141.864D1234.2"
Dim x = ExtractX(s, "X"c)
Dim y = ExtractX(s, "Y"c)

Operator * Not Defined for types char and string

I added two vb files to a new vs project and I seem to be having a problem with the last line of the code below. I get an error: Operator '*' is not defined for types 'Char' and 'String'.
I don't know too much about vb so can someone explain to me whats going on in this last line and how I may fix the error? mStream is a FileStream
Public Shared Function GetCharImage(Font As Integer, c As Char) As Bitmap
If UnicodeFonts.mStream Is Nothing Then
UnicodeFonts.Init()
End If
' The following expression was wrapped in a checked-statement
UnicodeFonts.mStream = UnicodeFonts.Stream(Font - 1)
UnicodeFonts.mReader = UnicodeFonts.Reader(Font - 1)
' The following expression was wrapped in a checked-expression
UnicodeFonts.mStream.Seek(CLng(c * ""), 0)
Edit ***
the line that calls the above method is this:
array(i - 1) = UnicodeFonts.GetCharImage(Font, CharType.FromString(Strings.Mid(Text, i)))
from the following method:
Public Shared Function GetStringImage(Font As Integer, Text As String) As Bitmap
' The following expression was wrapped in a checked-statement
Dim array As Bitmap() = New Bitmap(Strings.Len(Text) - 1 + 1 - 1) {}
Dim arg_19_0 As Integer = 1
Dim num As Integer = Strings.Len(Text)
Dim num2 As Integer
Dim height As Integer
For i As Integer = arg_19_0 To num
array(i - 1) = UnicodeFonts.GetCharImage(Font, CharType.FromString(Strings.Mid(Text, i)))
num2 += array(i - 1).Width
If array(i - 1).Height > height Then
height = array(i - 1).Height
End If
Next
Dim bitmap As Bitmap = New Bitmap(num2, height, PixelFormat.Format32bppArgb)
Dim graphics As Graphics = Graphics.FromImage(bitmap)
Dim arg_8C_0 As Integer = 1
Dim num3 As Integer = Strings.Len(Text)
For j As Integer = arg_8C_0 To num3
Dim num4 As Integer
graphics.DrawImage(array(j - 1), num4, 0)
num4 += array(j - 1).Width
Next
Dim arg_C4_0 As Integer = 1
Dim num5 As Integer = Strings.Len(Text)
For k As Integer = arg_C4_0 To num5
array(k - 1).Dispose()
Next
graphics.Dispose()
Return bitmap
End Function
The code is working with a file containing fonts.
My best guess is that you're trying to find the data for a font character at a specific offset within a file, based on the character code.
You could try something like:
UnicodeFonts.mStream.Seek(CLng(c) * 4), 0)
I've chosen 4 here, on the assumption whatever you're looking for is in a table of 4-byte integers.
The change here is that I'm converting c to a number using CLng(c) first, then multiplying this by another number, instead of a string.
The problem is that you are trying to multiply a character and a string: c * "" Characters and strings are not numbers, so they cannot be multiplied together.