VBA excel, strange behavior when converting range to html - html

I've been trying my hand at some code that is supposed to convert a range in a worksheet to an html table. It seems to work fine mostly. But sometimes populates the rows multiple times, meaning there would be only 2 rows to copy in the active sheet, but the html table output contains repetitions of the header and data rows in the table rows of the html code. The funny thing is if I set a break point just after counting rows and columns the bug seems to occur less often. I'm really lost here could anybody shed some light on this?
I am using the following code:
' establish number of columns and rows to send
Report.Activate 'this is a worksheet object
NumbofRows = Report.Range("A1", Range("A1").End(xlDown)).Rows.Count
NumbofCols = Report.Range("A1", Range("A1").End(xlToRight)).Columns.Count
' Populate headers
TableHeaders = "<table> <tr>"
For i = 1 To NumbofCols
TableHeaders = TableHeaders & "<th>" & Report.Cells(1, i) & "</th>"
Next i
TableHeaders = TableHeaders & "</tr>"
' populate response rows
For y = 2 To NumbofRows
If WorksheetFunction.IsEven(y) Then
Style = "style= " & Chr(39) & "background:#CCEBFF" & Chr(39)
Else
Style = "style= " & Chr(39) & "background:#E6F5FF" & Chr(39)
End If
' loop through cells on the current row and add them to the table
TableRows = TableRows & "<tr " & Style & ">"
For x = 1 To NumbofCols
TableRows = TableRows & "<td>" & Report.Cells(y, x) & "</td>"
Next x
TableRows = TableRows & "</tr>"
Next y
' close table tag
TableRows = TableRows & "</table> <br> <br>"
'stick them together
ResponseTable = TableHeaders & TableRows

A common error when relying upon ActiveSheet is to specify a cell range's parent while failing to specify the same parent on the cells that mark the start and stop of the range. Example:
NumbofRows = Report.Range("A1", Report.Range("A1").End(xlDown)).Rows.Count
NumbofCols = Report.Range("A1", Report.Range("A1").End(xlToRight)).Columns.Count
I would wrap this whole segment of code into a With ... End With code block and prefix each cell/range definition with a .. The . specifies that each reference belongs to the parent defined with the With ... End With code.
With Report
' establish number of columns and rows to send
'.Activate 'NOT NECESSARY
NumbofRows = .Range("A1", .Range("A1").End(xlDown)).Rows.Count
NumbofCols = .Range("A1", .Range("A1").End(xlToRight)).Columns.Count
' Populate headers
TableHeaders = "<table> <tr>"
For i = 1 To NumbofCols
TableHeaders = TableHeaders & "<th>" & .Cells(1, i) & "</th>"
Next i
TableHeaders = TableHeaders & "</tr>"
' populate response rows
For y = 2 To NumbofRows
If CBool(y Mod 2) Then
Style = "style= " & Chr(39) & "background:#E6F5FF" & Chr(39)
Else
Style = "style= " & Chr(39) & "background:#CCEBFF" & Chr(39)
End If
' loop through cells on the current row and add them to the table
TableRows = TableRows & "<tr " & Style & ">"
For x = 1 To NumbofCols
TableRows = TableRows & "<td>" & .Cells(y, x) & "</td>"
Next x
TableRows = TableRows & "</tr>"
Next y
' close table tag
TableRows = TableRows & "</table> <br/> <br/>"
'stick them together
ResponseTable = TableHeaders & TableRows
End With
That should take care of errant behavior and free you from relying upon ActiveSheet for the parentage of cell/range references.
Your use of Report.Range("A1").End(xlDown) to define the extent of a range is a bit troublesome. With no rows in the table beyond a header row, you are defining all rows to the bottom of the worksheet.

Related

VBScript to output that outputs an HTML table

I am attempting to read a text file that contains rows and then output them in the form of columns in an html file. I have no problem having this work when using WScript.echo to display it on the screen, but I am unable to get it to a table in an HTML file. I am getting the following error when attempting to run the vbs file: Type mismatch: 'OpenTextFile'. Any guidance would be much appreciated
Dim fso : Set fso = CreateObject("Scripting.FileSystemObject")
Dim OutputHTML : Set OutputHTML = fso.CreateTextFile("C:\Users\Istaley.RXDATA\Desktop\NewEmployeeTest\Part2_TableData.html")
Dim file : Set file = fso.OpenTextFile("C:\Users\Istaley.RXDATA\Desktop\NewEmployeeTest\Part2_data.txt", 1, True)
Dim fc : fc = file.ReadAll : file.close : Dim fcArray : fcArray = Split(fc, vbCrLf)
OutputHTML.WriteLine "<html>"
OutputHTML.Writeline "<body>"
OutputHTML.WriteLine "<table BORDER=1>"
Dim opArray() : ReDim opArray(0)
For Each row In fcArray
Dim tmp: tmp = Split(row, "|")
For ent=0 To UBound(tmp)
If ent > UBound(opArray) Then
ReDim Preserve opArray(UBound(opArray)+1)
opArray(ent) = Trim(tmp(ent))
Else
If Len(opArray(ent)) > 0 Then
OutputHTML.WriteLine "<tr>"
opArray(ent) = opArray(ent) & " " & Trim(tmp(ent))
OutputHTML.WriteLine "</tr>"
Else
opArray(ent) = Trim(tmp(ent))
End If
End If
Next
Next
WScript.echo Join(opArray, vbCrLf)
OutputHTML.WriteLine "</table>"
OutputHTML.WriteLine "</body>"
OutputHTML.WriteLine "</html>"
OutputHTML.Write Join(opArray, vbCrLf) : OutputHTML.Close
I know it's an old topic, but this might be useful to anyone looking to do the same, like I did. It's a bit rushed, but I've added comments inline. Bits have been taken from a number of locations, so it's not all my own work...
Function LoadFile(File)
On Error Resume Next
'Declaire all variables
Dim fso,F,ReadText,strError
Dim ReadArray
Dim ReadHTMLOutput, ReadRowCount, ReadRowItem, ReadRowItemSplit, ReadElementCount, ReadElementItem
'Create the object to read files
Set fso = CreateObject("Scripting.FileSystemObject")
'Set the file to read and the format
Set F = fso.OpenTextFile(File,1)
'If there's a problem, say so...
If Err.Number <> 0 Then
strError = "<center><b><font color=Red>The file "& File &" dosen't exists !</font></b></center>"
OutputTable.InnerHTML = strError
Exit Function
End If
'Read the contents of the file into ReadText
ReadText = F.ReadAll
'Split the text based on Carriage return / Line feed
ReadArray = Split(ReadText,vbCrLf)
'fill the output variable with the HTML of the start of the table
ReadHTMLOutput = "<table border=" & chr(34) & "2" & chr(34) & ">" & vbcrlf
'starting at 0 until the last line in the array, run through each line
For ReadRowCount=0 to UBound(ReadArray)
'Take the whole row into it's own variable
ReadRowItem = ReadArray(ReadRowCount)
'Split the row (separated by commas) into an array
ReadRowItemSplit = Split(ReadRowItem,",")
'Add the HTML for the row of the table
ReadHTMLOutput = ReadHTMLOutput & "<tr>" & vbcrlf
'starting at 0 until the last entry of the row array, run through each element
For ReadElementCount=0 to UBound(ReadRowItemSplit)
'Read the element into a variable
ReadElementItem = ReadRowItemSplit(ReadElementCount)
'If the element is blank, put a space in (stops the cell being formatted empty)
If ReadElementItem = "" Then ReadElementItem = " "
'Add the HTML for the cell of the row of the table
ReadHTMLOutput = ReadHTMLOutput & "<td>" & ReadElementItem & "</td>" & vbcrlf
'Go to the next element in the row
Next
'Add the HTML for the end of the row of the table
ReadHTMLOutput = ReadHTMLOutput & "</tr>" & vbcrlf
'Go to the next row in the file
Next
'Add the HTML for the end of the table
ReadHTMLOutput = ReadHTMLOutput & "</table>" & vbcrlf
'Fill the DIV with the contents of the variable
OutputTable.InnerHTML = ReadHTMLOutput
End Function
and in the HTML:
<div id="OutputTable"></div>
That way, the DIV is filled with the HTML from ReadHTMLOutput
The issue is this line.. The first argument of OpenTextFile takes a string, but you have passed it an Object. You've already opened the text file for writing using CreateTextFile.
Set WriteOutput = fso.OpenTextFile(OutputHTML, 8, True)
Get rid of this line and change all remaining instances of WriteOutput to OutputHTML.

left align a cell contents in html table

I am sending an e-mail from Excel using Outlook. I am sending the message as an html message. The message sends but not in the format I expect. The headers are fine but the cells below do not left align as I expect.
How do I get the cells below the header to be left aligned? I thought by using the align attribute it should be fine?
My code
Private Function CreateHTMLMsg() As String
Dim msg As String
Dim colourMkt As String
Dim colourBid As String
Dim colourAsk As String
Dim i As Integer
msg = "<table style='font-size: 12pt;'><tr></tr><tr><th align='left'>Fund</th><th> </th>" & _
"<th align='left'>Mkt Spread</th><th> </th>" & _
"<th align='left'>Bid Spread</th><th> </th>" & _
"<th align='left'>Ask Spread</th><th> </th></tr>"
For i = 1 To UBound(pBreaches)
If pBreaches(i).SendEmail = True Then
If pBreaches(i).BreachedMkt = True Then
colourMkt = "yellow"
Else
colourMkt = "transparent"
End If
If pBreaches(i).BreachedBid = True Then
colourBid = "yellow"
Else
colourBid = "transparent"
End If
If pBreaches(i).BreachedAsk = True Then
colourAsk = "yellow"
Else
colourAsk = "transparent"
End If
msg = msg & "<tr style='font-size: 10pt;'><td>" & pBreaches(i).Fund & "</td><td> </td><td>" & _
"<td align='left' style='background-color:" & colourMkt & "'>" & pBreaches(i).SpreadMkt & "</td><td> </td><td>" & _
"<td align='left' style='background-color:" & colourBid & "'>" & pBreaches(i).SpreadBid & "</td><td> </td><td>" & _
"<td align='left' style='background-color:" & colourAsk & "'>" & pBreaches(i).SpreadAsk & "</td><td> </td><td></tr>"
End If
Next i
CreateHTMLMsg = msg & "</table>"
End Function
Try with :
style="float: left;" (HTML)
float: left; (CSS)
Here is more infos about HTML table and CSS about it : Complete Guide to the Table element

Excel formula to change cell background color and/or set text bold

I have a .net application which generates excel from simple string variable where every cell gets its value like this:
For iCol = 0 To Cols.Rows.Count - 1
str &= Trim(Cols.Rows(iCol)("capt")) & vbTab
Next
I am looking for a way to change cell background and/or set text bold via excel formula.
Something like
str &= "=<b>"
str &= Trim(Cols.Rows(iCol)("capt"))
str &= "</b>"
or
str &= "=<p bgcolor=" + "color" + ">"
str &= Trim(Cols.Rows(iCol)("capt"))
str &= "</p>"
Macro or conditional-formatting is not an option.
You're looking for the Range.Font and Range.Interior properties.
For iCol = 0 To Cols.Rows.Count - 1
str &= Trim(Cols.Rows(iCol)("capt")) & vbTab
Cells(row, iCol).Font.Bold = True
Cells(row, iCol).Interior.Color = ColorConstants.vbCyan
Next

Alternating Colors of Rows with HTML

I am currently writing code in VBA to automate a process that sends out an e-mail that contains a table with information generated by a query in an Access database. I am using HTML to format the table in that e-mail, and I need the colors of the rows in that table to alternate colors (odd rows: #ccffcc; even rows: #ffffff), but I cannot seem to figure it out. I have tried to use the child selector, but I cannot see to figure out to get that to work in here. I do not have much experience or knowledge related to CSS or HTML, so I very well could have been using the child selector incorrectly.
Here is what I currently have:
Bodytext2 = "<html>" & _
"<body>" & _
"<TABLE BORDER=0 CELLpadding=0 style='font-family:Arial; font-size:12px'>" & _
"<TBODY>" & _
"<TH bgcolor='#dcdcdc'> Field1 </TH>" & _
"<TH bgcolor='#dcdcdc'> Field2 </TH>" & _
"<TH bgcolor='#dcdcdc'> Field3 </TH>"
'Creates the table
Set rst = mydb.OpenRecordset("Query In Access")
Do Until rst.EOF
Bodytext2 = Bodytext2 & _
"<TR ALIGN=CENTER VALIGN=MIDDLE>" & _
"<TD> " & rst![Field1] & _
"<TD> " & rst![Field2] & _
"<TD> " & rst![Field3]
rst.MoveNext
Loop
rst.Close
Bodytext2 = Bodytext2 & "</table>"
This code produces the correct table with the correct information. however, I am not sure where to add in the code to change the colors of the table's rows, or how to even write the code to do that. My guess so far is that it would be in the "TR Align=center valign=middle" portion, but that is just my guess.
I have looked a lot of other answers on here, but I think that my lack of knowledge in this field is making it difficult for me to determine what I actually need and where it needs to go. So, if there are helpful answers to similar questions that y'all could direct me to, I would greatly appreciate that too.
Thank You!
Create a counter variable before you go into your loop that will let you keep track of your row number, like this:
i = 1
Do Until rst.EOF
If i Mod 2 = 0 Then
Bodytext2 = Bodytext2 & "<TR ALIGN=CENTER VALIGN=MIDDLE BGCOLOR='#ffffff'>"
Else
Bodytext2 = Bodytext2 & "<TR ALIGN=CENTER VALIGN=MIDDLE BGCOLOR='#ccffcc'>"
End If
Bodytext2 = Bodytext2 & _
"<TD> " & rst![Field1] & _
"<TD> " & rst![Field2] & _
"<TD> " & rst![Field3]
rst.MoveNext
i = i + 1
Loop
My apologies for any syntax errors. My VBA is a little rusty.

html table in webbrowser (VB)

I'm working on creating a table from an access database. It cycles through the database finding any matches and then displays them in a webbrowser.
Currently I have rows showing but I'd love to do an onclick show the rows below. I'm not sure if it's even possible with this type of layout. Thoughts on a different approach?
Private Sub Populate_HtmlTable(ByRef dt As DataTable)
Dim table As String = "<html>" & vbCrLf & _
"<head>" & vbCrLf & _
"</head>" & vbCrLf & _
"<body > " & vbCrLf & _
"<table>"
Label5.Text = "RESULTS RETURNED : " + dt.Rows.Count.ToString
If dt.Rows.Count = False Then
table += "<tr><td> No Results Returned</td> </tr>"
Else
For i As Integer = 0 To dt.Rows.Count - 1
table += "<tr>"
Dim tCellDataItem As New HtmlTableCell()
Dim tCellIntervention As New HtmlTableCell()
Dim tCellTags As New HtmlTableCell()
Dim tCellPR As New HtmlTableCell()
Dim tCellGrade As New HtmlTableCell()
Dim tCellRR As New HtmlTableCell()
Dim tCellEvidence As New HtmlTableCell()
Dim tCellBibliography As New HtmlTableCell()
'Cell Intervention Title
Dim data_item As String = ""
If Not IsDBNull(dt.Rows(i)("data_item")) Then data_item = "<strong>" + dt.Rows(i)(1).ToString() + "</strong><br>"
tCellDataItem.InnerHtml = data_item
'Cell Intervention
Dim intervention As String = ""
If Not IsDBNull(dt.Rows(i)("intervention")) Then intervention = dt.Rows(i)(3).ToString()
tCellIntervention.InnerHtml = intervention
'Cell Tags
Dim tags As String = ""
If Not IsDBNull(dt.Rows(i)("Tags")) Then tags = dt.Rows(i)(10).ToString()
tCellTags.InnerHtml = tags
'Add Cells to Rows and then add Rows to table
table += "<td valign=""top"">" + tCellDataItem.InnerHtml + "</td>"
'table += "</tr>"
'1st Drop Down'
'Interventions
//IF THEY CLICK HERE
table += "<tr><td style=""border:solid; border-bottom-width:2px;""> Intervention Description</td> </tr>"
//DISPLAY THESE ROWS
table += "<tr><td>" + tCellIntervention.InnerHtml + "</td></tr>"
table += "<tr><td> </td></tr>"
table += "<tr><td><strong>Tags: </strong>" + tCellTags.InnerHtml + "</td></tr>"
table += "<tr><td> </td></tr>"
//MORE Info cut out similar to above.
Next
End If
table += "</table></body></html>"
My.Computer.FileSystem.DeleteFile(Application.StartupPath + "\site.html")
My.Computer.FileSystem.WriteAllText(Application.StartupPath + "\site.html", table, True)
WebBrowser1.Navigate(Application.StartupPath + "\site.html")