I'm working on an SSRS 2008 R2 report and I'm displaying images dynamically. I would like to hide the image box and display an icon with text that reads "Image not found" if the image doesn't exist on our report server.
I've tried a few things with expressions, but I can't get them to correctly return true or false, based on if the image exists or not.
The expression I'm using to display the image is:
="/BusinessIntelligence/Drilldown Reports/" + Fields!item.Value + ".jpg"
To test if I could get the report to detect whether the image existed, I dragged a textbox onto my report and tried the following expressions in an attempt to return True or False.
=IIf(IsNothing("/BusinessIntelligence/Drilldown Reports/" + Fields!item.Value + ".jpg"), "Woohoo!", "Do'h!") this always returns False, even if the image exists.
I even tried using some custom code I found here.
Code:
Function IsValid(ByVal Url As String) As Boolean
Dim sStream As IO.Stream
Dim URLReq As Net.HttpWebRequest
Dim URLRes As Net.HttpWebResponse
Try
URLReq = Net.WebRequest.Create(Url)
URLReq.Credentials = System.Net.CredentialCache.DefaultCredentials
URLRes = URLReq.GetResponse()
sStream = URLRes.GetResponseStream()
Dim reader As String = New IO.StreamReader(sStream).ReadToEnd()
Return True
Catch ex As Exception
Return False
End Try
End Function
And the expression I used for that code is:
=IIf(Code.IsValid("/BusinessIntelligence/Drilldown Reports/" + Fields!item.Value + ".jpg"), "Woohoo!", "Do'h!")
But this also always just returns false.
ok, I needed this thanks.
Your error here is you are using a reserve word for a webpage IsValue. Change your function name to IsThere and it should work famously.
Related
good afternoon,
I have an access with a subform (sub_frm_robo2) that has a specific column (CD_SENHA).
In the Form Load event I put the code: (Me.sub_frm_robo2.Form! SENHA.InputMask = "Password")
and I am trying to create a condition that at the moment this Column
(CD_SENHA) receives focus (Me.sub_frm_robo2.Form!SENHA.SetFocus),
the data mask be removed (Me.sub_frm_robo2.Form!SENHA.InputMask = "")
and when the focus changes to the next column return the data mask to the initial format (Me.sub_frm_robo2.Form! PASSWORD = "Password")
Below some images to better exemplify
Before Focus
With Focus
After Focus
I think the code would look something like this
Do While Me.sub_frm_robo2.SetFocus = True
If Me.sub_frm_robo2.Form!SENHA.SetFocus Then
Me.sub_frm_robo2.Form!SENHA.InputMask = ""
End If
Next
Can you help me?
Well, I did not have any help here but I managed to resolve after a few attempts and errors, just to code a code in the event of each column of the subformaluario to make it work. Good luck to everyone
Private Sub CNPJ_AF_GotFocus()
Me.Form!SENHA.InputMask = "Password"
End Sub
Private Sub SENHA_GotFocus()
Me.Form!SENHA.InputMask = ""
End Sub
My goal is to fill a LibreOffice calc sheet, and silently send a cell range by email when the user clicks the send-off button (and once more to confirm).
So there is three part to this.
A push button with a request to confirm. (Easy and done.)
Select Cell Range and turn it into rich text format (Haven't yet found)
Send rich text email from within the sheet. (Will tackle the "silent" part later)
I tried copying the range to the clipboard with unoService but it seemed over-complicated and full of errors.
Here's what I have:
''''Send by e-mail enriched text
Sub Main
Dim Doc, Sheet, Range, Rtf, Exec as Object
End Sub
'Confirm it
Sub SendTableApproval
If MsgBox ("Ready to email?", MB_YESNO + MB_DEFBUTTON2) = IDYES Then
CopyTable()
End If
End Sub
'Copy it
Sub CopyTable
Doc = ThisComponent
View = Doc.CurrentController
Frame = View.Frame
Sheet = Doc.Sheets.getByIndex(0)
Range = Sheet.getCellrangeByName("a1:f45")
Exec = createUnoService("com.sun.star.frame.DispatchHelper")
View.Select(Range)
Cells = View.getTransferable()
Exec.executeDispatch(Frame, ".uno:Deselect", "", 0, array())
'SimpleMailTo(Cells)
End Sub
'Mail it
Sub SimpleMailTo(body)
Dim launcher as object
Dim eAddress, eSubject, eBody, aHTMLanchor as string
launcher = CreateUnoService("com.sun.star.system.SystemShellExecute")
eAddress = "tu#domo.eg"
eSubject = "Cotidie agenda futuendane"
eBody = body
aHTMLanchor = "mailto:" & eAddress & "?subject=" & eSubject & "&&body=" & eBody
launcher.execute(aHTMLanchor, "", 0)
End Sub
I still do not know after three days of research over methods, properties, uno.
My question is, simply put, How can I convert a transferable content to HTML/RTF?
Simply copying and pasting into an email produces the result you are asking for. The code on the LibreOffice side should look like this.
dispatcher.executeDispatch(document, ".uno:Copy", "", 0, Array())
It sounds like you already tried this, but something didn't work. Perhaps you could elaborate on what went wrong.
Another approach would be to write the spreadsheet to a temporary HTML or XHTML file. Then parse the temporary file to grab the part needed for the email.
AFAIK there is no such command to turn a cell range into rich text format with UNO. To do it that way, you would need to loop through each text range of each cell, read its formatting properties and then generate the HTML yourself.
EDIT:
Good idea about XTransferable. The following Java code adapted from the DevGuide gets an HTML string and then prints it. I believe this would be a good solution for your needs.
public void displayHTMLFromClipboard()
{
try
{
Object oClipboard = xMCF.createInstanceWithContext(
"com.sun.star.datatransfer.clipboard.SystemClipboard", xContext);
XClipboard xClipboard = (XClipboard)
UnoRuntime.queryInterface(XClipboard.class, oClipboard);
XTransferable xTransferable = xClipboard.getContents();
DataFlavor[] aDflvArr = xTransferable.getTransferDataFlavors();
System.out.println("Available clipboard formats:");
DataFlavor aChosenFlv = null;
for (int i=0;i<aDflvArr.length;i++)
{
System.out.println(
"MimeType: " + aDflvArr[i].MimeType +
" HumanPresentableName: " + aDflvArr[i].HumanPresentableName );
if (aDflvArr[i].MimeType.equals("text/html"))
{
aChosenFlv = aDflvArr[i];
}
}
System.out.println("");
try
{
if (aChosenFlv != null)
{
System.out.println("HTML text on the clipboard...");
Object aData = xTransferable.getTransferData(aChosenFlv);
String s = new String((byte[])aData, Charset.forName("ISO-8859-1"));
System.out.println(s);
}
}
catch (UnsupportedFlavorException exc)
{
exc.printStackTrace();
}
}
catch(com.sun.star.uno.Exception exc)
{
exc.printStackTrace();
}
}
If you plan to use Basic, it might be a good idea to do some research into the proper way to convert bytes. The code I have below seems to work but is probably unreliable and unsafe, and will not work for many languages. A few of my initial attempts crashed before this finally worked.
Sub DisplayClipboardData
oClipboard = createUnoService("com.sun.star.datatransfer.clipboard.SystemClipboard")
xTransferable = oClipboard.getContents()
aDflvArr = xTransferable.getTransferDataFlavors()
For i = LBound(aDflvArr) To UBound(aDflvArr)
If aDflvArr(i).MimeType = "text/html" Then
Dim aData() As Byte
aData = xTransferable.getTransferData(aDflvArr(i))
Dim s As String
For j = LBound(aData) to UBound(aData)
s = s & Chr(aData(j)) 'XXX: Probably a bad way to do this!
Next j
Print(s)
End If
Next
End Sub
One more suggestion: Python might be a better language choice here. In many ways, using Python with LibreOffice is easier than Java. And unlike Basic, Python is powerful enough to comfortably handle byte strings.
I'm Having a problem regarding to the autocomplete textbox. First I already made the autocomplete textbox work with mysql database as custom source but the default textfilter of autocomplete is "start with" not "contains". I want to change the textfilter to "contains", so that when I search any part of the string, the whole name which contains the searched word will appear in the autocomplete suggestions.
Can anyone help me fix my code?
This is the code i've done so far:
txtSearch.AutoCompleteMode = AutoCompleteMode.SuggestAppend
txtSearch.AutoCompleteSource = AutoCompleteSource.CustomSource
Dim DataCollection As New AutoCompleteStringCollection()
Dim query As String
sqlcon = New MySqlConnection
sqlcon.ConnectionString =
"server=localhost;userid=root;password=root;database=svfmemberlistdb"
Try
sqlcon.Open()
query = " SELECT Name FROM svfmemberlistdb.svfmemberlist "
sqlcmd = New MySqlCommand(query, sqlcon)
sqladr.SelectCommand = sqlcmd
sqladr.Fill(ds)
sqladr.Dispose()
sqlcon.Close()
For Each row As DataRow In ds.Tables(0).Rows
If row.ToString.Contains(txtSearch.Text) Then
DataCollection.Add(row(0).ToString())
End If
Next
Catch ex As Exception
End Try
txtSearch.AutoCompleteCustomSource = DataCollection
I quote here Mitja Bonca's answer on MSDN.
In this case, autocompletemode will just not do. Its code is not meant
for something like it.
You will have to do your own code, to do the filtering on each letter
press.
So I would suggest not to use autocompletemode, and get all the data
(names) into dataTable. When user presses some button ("1" for
example), you start with your filtering, by creating new Datatable
(leave the main one untached - so you can return back to all data when
clearing comboBox by backspace), with Copy() method - to create a full
copy of original one, and use Select method to do the filteing.
This should look something like by using % simbol on both sides of a
string - to filter inbetween - this is what you want!
DataTable AllNames = new DataTable();
//fill it up and leave it untouched!
//to filter comboBox with names that contains pressed characters do in
private void comboBox1_KeyPress(object sender, KeyPressEventArgs e)
{
string name = string.Format("{0}{1}", comboBox1.Text, e.KeyChar.ToString()); //join previous text and new pressed char
DataRow[] rows = table.Select(string.Format("FieldName LIKE '%{0}%'", name));
DataTable filteredTable = AllNames.Clone();
foreach(DataRow r in rows)
filteredTable.ImportRow(r);
comboBox1.DataSource = null;
comboBox1.DataSource = filteredTable.DefaultView;
comboBox1.DisplayMember = "FieldName";
}
Reference
EDIT: This is of course a c# answer not VB.NET but it might be helpful to get the concept.
i Placed this code in my report property code
Public Function PageNumber() as String
Dim str as String
str = Me.Report.Globals!PageNumber.ToString()
Return str
End Function
and called in my text box in body of report Like this
=Code.PageNumber()
It was not able to repeat textbox on each page.
It is showing the page number as 1 only on first page.
need to show pagenumber in each page of the output in body of the report
Kindly help me on this if u have any solution.
First Follow the steps 1 below to do pagination:
1)
1.1. Click the Details group in the Row Groups pane.
1.2. From the Tablix member Properties pane, expand “Group”-> “PageBreak”.
1.3. Set the “BreakLocation” to “End” and set the “Disable” property to the expression like below:
=IIF(rownumber(nothing) mod 40=0,false,true)
The above point 1 is use to do pagination in Report output(Display only 40 records per page in output)
2) use custom code:
Public Function PageNumberno(val as integer) as String
Dim str as String
str =(val/40)
Return str
End Function
3) Create Calculated column in Dataset and enter =0 in expression
4) In 2 Calculated Column
1)Pageno
2)No in Dataset
In Report Body use Expression for PageNo :
=code.PageNumberno(Rownumber("DataSet1"))
use Expression for No :
=IIF(Instr(code.PageNumberno(Rownumber("DataSet1"))
,".")<>0,
(Left(code.PageNumberno(Rownumber("DataSet1")),
(Instr(code.PageNumberno(Rownumber("DataSet1")),".")-1))+1)
,code.PageNumberno(Rownumber("DataSet1"))
)
5)Right click and insert column on Right Side and in Column name add code in Text box
=ReportItems!No.Value
Note: No is calculated Field column name.
6)Under AdvancedMode
IN Row Group select Static and Set RepeatOnNewPage Properties to True
In the Above Column created under point 5 will display correct page no in every page in body of the report
I have Tried and its working Fine..Try it.
I usually put a text box in the footer of the report (which will automatically display on every page) with the following line of code in it (no report property code needed):
="Page " & CStr(Globals!PageNumber) & " of " & CStr(Globals!TotalPages)
I created a custom color palette for my charts using a technique described on TechNet.
I also have a series of drill-through column charts, where you click on one column and it passes a parameter through to the next chart and so on, giving the appearance of drill-down.
My graphs consist of 3 types of labor, and have three colors on the main chart. When I drill down to the next chart, some of the categories do not have all three types of labor that the main one has. So the first color in the palette is assigned to the series, even though it was the second color on the previous chart. I'd like to avoid this, if possible.
So a data value is green on the first chart (2nd in the color order) and yellow on the next chart (1st in the color order). How do I make the graphs "remember" the total number of series groups that were in the first chart?
This is Reporting Services 2005.
You cannot fix this using custom colour palettes.
What you can do is assign the labour type a colour in the database (using HEX is easiest). Then pass that in in your data set. Then set the color property to you hex value.
Unfortunately this is not possible. I've been looking for this for quite some time...
I was able to solve this because I was using a custom color palette, implemented as a hash table. I basically serialized this information and passed it to a hidden parameter on the subreport and then reinflated the data structure.
It's not perfect, but it works for now.
' Define some globals, including the color palette '
Private colorPalette As String() = _
{"#FFF8A3", "#A9CC8F", "#B2C8D9", "#BEA37A", "#F3AA79", "#B5B5A9", "#E6A5A4", _
"#F8D753", "#5C9746", "#3E75A7", "#7A653E", "#E1662A", "#74796F", "#C4384F", _
"#F0B400", "#1E6C0B", "#00488C", "#332600", "#D84000", "#434C43", "#B30023"}
' color palette pulled from SAP guidelines '
' http://www.sapdesignguild.org/resources/diagram_guidelines/color_palettes.html '
Private count As Integer = 0
Private colorMapping As New System.Collections.Hashtable()
' Create a custom color palette '
Public Function GetColor(ByVal groupingValue As String) As String
If colorMapping.ContainsKey(groupingValue) Then
Return colorMapping(groupingValue)
End If
Dim c As String = colorPalette(count Mod colorPalette.Length)
count = count + 1
colorMapping.Add(groupingValue, c)
Return c
End Function
' In custom actions of the data value, set the results of this '
' function to the mapping parameter in the next report '
Public Function PassColorMapping() As String
If colorMapping.Count = 0 Then
Return Nothing
End If
Try
' convert the hashtable to an array so it can be serialized '
Dim objHash As Object()() = ToJaggedArray(colorMapping)
' serialize the colorMapping variable '
Dim outStream As New System.IO.StringWriter()
Dim s As New System.Xml.Serialization.XmlSerializer(GetType(Object()()))
s.Serialize(outStream, objHash)
' move on to the next report '
Return outStream.ToString()
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Function
I ran into an issue where I couldn't find the equivalent of the onLoad event for the report. Since I wasn't sure where to put this inflate code, I stuck it in the background color of the plot area. Hence I always return "WhiteSmoke". I'll change this if I can find the right place to put it.
' Call this function when the report loads to get the series groups '
' that have already been loaded into the custom color palette '
' Pass in the parameter used to store the color mapping '
Public Function InflateParamMapping(ByVal paramMapping As Parameter) As String
Try
If paramMapping.Value Is Nothing Then
Return "WhiteSmoke"
ElseIf colorMapping.Count = 0 Then
Dim pXmlized As String = paramMapping.Value
' deserialize the mapping parameter '
Dim s As New System.Xml.Serialization.XmlSerializer(GetType(Object()()))
' get the jagged array and convert to hashtable '
Dim objHash As Object()() = DirectCast(s.Deserialize(New System.IO.StringReader(pXmlized)), Object()())
' stick the result in the global colorMapping hashtable '
colorMapping = ToHashTable(objHash)
count = colorMapping.Count
End If
Catch ex As Exception
' MsgBox(ex.Message) '
End Try
Return "WhiteSmoke"
End Function
ToJaggedArray() and ToHashTable() are helper functions because a HashTable is not serializable since they implement an IDictionary. I was in a hurry so I just converted them to an array right quick. Code comes from the Collection Serialization in ASP.NET Web
Services article written by Mark Richman. I converted the code from C# to VB.NET to use in the report.
Public Function ToJaggedArray(ByVal ht As System.Collections.HashTable) As Object()()
Dim oo As Object()() = New Object(ht.Count - 1)() {}
Dim i As Integer = 0
For EAch key As Object in ht.Keys
oo(i) = New Object() {key, ht(key)}
i += 1
Next
Return oo
End Function
Public Function ToHashTable(ByVal oo As Object()()) As System.Collections.HashTable
Dim ht As New System.Collections.HashTable(oo.Length)
For Each pair As Object() In oo
Dim key As Object = pair(0)
Dim value As Object = pair(1)
ht(key) = value
Next
Return ht
End Function
Now in the report itself you need to do a couple things.
Add a reference to System.Xml in Report Properties in both reports.
In the Actions of your parent report, set the Parameter containing your data structure to =Code.PassColorMapping()
In the Plot Area section of your report, put this expression for the background: =Code.InflateParamMapping(Parameters!colorMapping)
And of course, in the Fill for your data Series Style on both charts put this expression: =Code.GetColor(Fields!Type.Value)
You can continue doing this for as many subreports as you want - I currently have 3 levels of drill-through and it works fine.
I solved that extremely easy.
In my parent report I have lets say 12 series fields, each one getting their own color in a chart, on my child report I just keep all series on the chart, for instance going from a column chart to a line chart using drill down, but I control the visibility of them...
So in the child report in Series Properties -> Visibility I just add an expression:
=(Fields!ContentType.Value <> Parameters!ContentType.Value)
This way the report only keeps the visibility of the clicked value and hides all the others and the colors remains the same :)