Reputation:
I know there has to be a cleaner, more concise way to do this... but I'm not getting anywhere trying to Google for it. Basically, I have a set of data that I need to write to an HTML table.
The table comes out looking something like this (but much longer):
DOB SDLW SDLY WTD LWTD Start Date: 03/06/2013 02/27/2013 03/07/2012 03/04/2013 02/25/2013 End Date: 03/06/2013 02/27/2013 Net Sales 5,661.47 4,876.82 16.1% 5,765.33 -1.8% 13,941.10 13,310.09 4.7% Gross Sales 6,499.14 5,549.94 17.1% 6,602.71 -1.6% 16,046.50 15,306.56 4.8% Guest Count 369.00 317.00 16.4% 392.00 -5.9% 920.00 872.00 5.5% Total Comps 187.29 102.46 82.8% 163.19 4.8% 499.74 455.82 9.6% Total Voids 56.25 51.05 10.2% 131.65 -57.3% 161.05 227.83 -29.3%
The by-line issue:
Originally I had written this using an HtmlTextWriter
, but having to call AddAttribute()
for each <td>
made an incredible amount of (noisy) code. I then moved to wrappers, so I can least reduce a cell to a single line of code:
public string wrapAmntCell(Object input)
{
return "<td align=\"right\">" + string.Format("{0:n}", input) + " " + "</td>";
}
Which I don't particularly like still, but I've at least significantly improved where I started. However...
The bigger picture issue:
Is that I'm building these rows by concatenating strings of values that are built with += statements (cringe), something like this:
string[] finalNet = new string[validSites.Count];
string[] finalGross = new string[validSites.Count];
string[] finalGC = new string[validSites.Count];
string[] finalComp = new string[validSites.Count];
string[] finalVoid = new string[validSites.Count];
foreach (string num in validSites)
{
//SDLY
foreach (DataStore sdlyTmp in sdly)
{
if (sdlyTmp.siteNumber.Equals(num))
{
finalNet[countTD] += wrapAmntCell(sdlyTmp.netSales);
finalGross[countTD] += wrapAmntCell(sdlyTmp.grossSales);
finalGC[countTD] += wrapAmntCell(sdlyTmp.guestCount);
finalComp[countTD] += wrapAmntCell(sdlyTmp.compTotal);
finalVoid[countTD] += wrapAmntCell(sdlyTmp.voidTotal);
tmpCol03[0] = sdlyTmp.netSales;
tmpCol03[1] = sdlyTmp.grossSales;
tmpCol03[2] = sdlyTmp.guestCount;
tmpCol03[3] = sdlyTmp.compTotal;
tmpCol03[4] = sdlyTmp.voidTotal;
//percentage diff
finalNet[countTD] += wrapPctCell(getPctDiff(tmpCol01[0], tmpCol03[0]));
finalGross[countTD] += wrapPctCell(getPctDiff(tmpCol01[1], tmpCol03[1]));
finalGC[countTD] += wrapPctCell(getPctDiff(tmpCol01[2], tmpCol03[2]));
finalComp[countTD] += wrapPctCell(getPctDiff(tmpCol01[3], tmpCol03[3]));
finalVoid[countTD] += wrapPctCell(getPctDiff(tmpCol01[4], tmpCol03[4]));
//end diffs
totalsCol03[0] += sdlyTmp.netSales;
totalsCol03[1] += sdlyTmp.grossSales;
totalsCol03[2] += sdlyTmp.guestCount;
totalsCol03[3] += sdlyTmp.compTotal;
totalsCol03[4] += sdlyTmp.voidTotal;
}
}
}
(in writing that, I realize I could probably combine my inner foreach and the if statement nested in it using some .NET 3.5 magic; I'm still learning, and would appreciate guidance on that as well)
Where those Col arrays are used for percentage diffs.
At the end of all of my loops I end up with five arrays that contain full rows, from <tr>...</tr>
(19 cells of data per line), which I then loop back over foreach site again (as the information is stored positionally, Store1's data is located at finalNet[0], finalGross[0], etc) and write them to an HtmlTextWriter
.
Part of my issue is that my actual data is stored vertically (using an object that contains a full column for one date - these values are pulled from SQL queries based on the date in the column header) - whereas it has to be output horizontally in the table.
However, I'm having issues figuring out how to clean up this code and keep the format of my table intact. Any thoughts would be greatly appreciated.
Upvotes: 0
Views: 174
Reputation: 6578
I would suggest you use a view engine such as Razor. The project is open source and works outside of the ASP.Net runtime. This way you could separate your presentation (the generation of the HTML table) from your data generation. In this way you could write code along the lines of the following. Assuming that your data from your SQL queries is column orientated (as you suggested) and is a collection named data
C# code in your executable:
var data = ...;
var template = File.ReadAllText("path/to/razor/template.cshtml");
var html = Razor.Parse(template,data); //Bind the SQL data to the HTML
Razor template example:
<table>
@foreach(var row in Model) {
<tr>
@foreach(var col in row) {
<td>@col</td>
}
</tr>
}
</table>
Without knowing more of your code, it's a little difficult to give you a better example, but I think that this should lead you in the right direction
Upvotes: 0
Reputation: 41
I am totally agree with "Reddog". You should use gridview control and Pass your Data object as datasource to gridview. Also you can use JQGrid for client side scripting.
Upvotes: 0