Custom Report help

(imported topic written by abrice)

Hi,

I’m trying to create a report which looks like this:

Fixlet Installed Needed Not needed Unknown Failed Last Updated

Microsoft SP2 12 22 100 0 0 01/02/2007

I need this report to use some custom filters which I’ve already created and to be in CSV format so I can have it automatically emailed to a mail list. Basically what I would like is for everything to be in the report so when it’s emailed out it’s already formatted and filtered correctly.

Any help would be great.

(imported comment written by BenKus)

Hi abrice,

Do you want to do this for each Fixlet or for each action that is sent?

Ben

(imported comment written by abrice)

For each fixlet.

Ideally it would only show fixlets where at least one system had it relevent at one point in time. IE if there was a fixlet for a win98 patch, but there are no win98 systems it wouldn’t be listed but for example if only one system needed a win2000 patch it would be listed in the report with either the status of installed or needed with the remainder of the systems listed as “not needed”.

Hope that makes sense.

(imported comment written by JesseR91)

were you able to get this report made? I am curious as I would like something like this as well.

(imported comment written by abrice)

No, not yet. I’m hoping someone on this forum can help :slight_smile:

(imported comment written by JesseR91)

Ben should be able to whip something up :stuck_out_tongue:

(imported comment written by BenKus)

Hi abrice / jesseR,

How about this (I stole this from Jesse here at BigFix)… It is close to what you want:

<div><b>Last Updated: <?relevance now ?></b></div> <br> <table class=
"sortable" id=
"table1" border=1> <tbody> <th>Fixlet Name</th><th>Fixed</th><th>Needed</th><th>Not Needed</th> <?relevance concatenation of trs of   (   td of link of it &   (html tag (
"td", attr list of (
"class", 
"sum"), it)) of   (   it as string   )   of number of results   whose   (   exists last became nonrelevant of it and not relevant flag of it ) of it & (html tag (
"td", attr list of (
"class", 
"sum"), it)) of   (   it as string   )   of number of results   whose   (   relevant flag of it ) of it & (html tag (
"td", attr list of (
"class", 
"sum"), it)) of   (   it as string   )   of (number of bes computers - number of computers of results of it) )   of fixlets whose ( fixlet flag of it) of bes site whose (name of it = 
"Enterprise Security")   ?>   <tr class=sortbottom> <td><b>TOTALS</b></td>   <td></td> <td></td> <td></td>   </tr>   </tbody> </table>       <script type=
"text/javascript">       WriteSums();   
//WriteCumulativePrecentages();   sortables_init();       function WriteSums()   
{   var tables = document.getElementsByTagName(
'TABLE');     

for (var i = 0; i < tables.length; i++)   
{   var sums     = 

new Array();   var t            = tables+;   var rows      = t.rows;     

for (var j = 1; j < rows.length - 1; j++)   
{   var cells = rows[j].cells;     

for (var k = 0; k < cells.length; k++)   
{   

if (cells[k].className == 
"sum")   
{   

if (sums[k])   
{   sums[k] += parseFloat(cells[k].innerText);   
}   

else   
{   sums[k] = parseFloat(cells[k].innerText);   
}   
}   
}   
}   

for (var a = 0; a < sums.length; a++)   
{   

if (sums[a])   
{   t.rows[t.rows.length - 1].cells[a].innerText = sums[a];   
}   
}     
}   
}     function WriteCumulativePrecentages()   
{   lastCells = table1.rows[table1.rows.length - 1].cells;   lastCells[4].innerText = (parseInt( lastCells[1].innerText , 10 ) / parseInt( lastCells[3].innerText , 10 ) * 100).toFixed(2) + 
'%';   
}                     
/** The MIT Licence, for code from kryogenix.org Code downloaded from the Browser Experiments section of kryogenix.org is licenced under the so-called MIT licence. The licence is below. Copyright (c) 1997-date Stuart Langridge Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **/       var SORT_COLUMN_INDEX;       function sortables_init() 
{   
// Find all tables with class sortable and make them sortable   

if (!document.getElementsByTagName) 

return;   tbls = document.getElementsByTagName(
"table");   

for (ti=0;ti<tbls.length;ti++) 
{   thisTbl = tbls[ti];   

if (((
' '+thisTbl.className+
' ').indexOf(
"sortable") != -1) && (thisTbl.id)) 
{   
//initTable(thisTbl.id);   ts_makeSortable(thisTbl);     
}   
}   
}       function ts_makeSortable(table) 
{   

if (table.rows && table.rows.length > 0) 
{   var firstRow = table.rows[0];   
}   

if (!firstRow) 

return;     
// We have a first row: assume it's the header, and make its contents clickable links   
// Skip cells with class 'notsortable' -- JWK 09/15/2006   

for (var i=0;i<firstRow.cells.length;i++) 
{   var cell = firstRow.cells+;   

if (cell.className == 
'notsortable') 
{

continue;
}   var txt = ts_getInnerText(cell);   cell.innerHTML = 
'<a href="#" class="sortheader" '+   
'onclick="ts_resortTable(this, '+i+
');return false;">' +   txt+
'<span class="sortarrow">   </span></a>';   
}   
}       function ts_getInnerText(el) 
{   

if (typeof el == 
"string") 

return el;   

if (typeof el == 
"undefined") 
{ 

return el 
};   

if (el.innerText) 

return el.innerText;  
//Not needed but it is faster   var str = 
"";     var cs = el.childNodes;   var l = cs.length;   

for (var i = 0; i < l; i++) 
{   

switch (cs+.nodeType) 
{   

case 1: 
//ELEMENT_NODE   str += ts_getInnerText(cs+);   

break;   

case 3:        
//TEXT_NODE   str += cs+.nodeValue;   

break;   
}   
}   

return str;   
}       function ts_resortTable(lnk,clid) 
{   
// get the span   var span;   

for (var ci=0;ci<lnk.childNodes.length;ci++) 
{   

if (lnk.childNodes[ci].tagName && lnk.childNodes[ci].tagName.toLowerCase() == 
'span') span = lnk.childNodes[ci];   
}   var spantext = ts_getInnerText(span);   var td = lnk.parentNode;   var column = clid || td.cellIndex;   var table = getParent(td,
'TABLE');     
// Work out a type for the column   

if (table.rows.length <= 1) 

return;   var itm = ts_getInnerText(table.rows[1].cells[column]);   sortfn = ts_sort_caseinsensitive;   

if (itm.match(/^\d\d[\/-]\d\d[\/-]\d\d\d\d$/)) sortfn = ts_sort_date;   

if (itm.match(/^\d\d[\/-]\d\d[\/-]\d\d$/)) sortfn = ts_sort_date;   

if (itm.match(/^[£$]/)) sortfn = ts_sort_currency;   

if (itm.match(/^[\d\.]+$/)) sortfn = ts_sort_numeric;   SORT_COLUMN_INDEX = column;   var firstRow = 

new Array();   var newRows = 

new Array();   

for (i=0;i<table.rows[0].length;i++) 
{ firstRow+ = table.rows[0]+; 
}   

for (j=1;j<table.rows.length;j++) 
{ newRows[j-1] = table.rows[j]; 
}       newRows.sort(sortfn);       

if (span.getAttribute(
"sortdir") == 
'down') 
{   ARROW = 
'  &uarr;';   newRows.reverse();   span.setAttribute(
'sortdir',
'up');   
} 

else 
{   ARROW = 
'  &darr;';   span.setAttribute(
'sortdir',
'down');   
}     
// We appendChild rows that already exist to the tbody, so it moves them rather than creating new ones   
// don't do sortbottom rows   

for (i=0;i<newRows.length;i++) 
{ 

if (!newRows+.className || (newRows+.className && (newRows+.className.indexOf(
'sortbottom') == -1))) 
{ table.tBodies[0].appendChild(newRows+); 

if (i % 2 > 0) newRows+.className = 
'wr_oddRow'; 

else newRows+.className = 
'wr_evenRow';
}
}   
// do sortbottom rows only   

for (i=0;i<newRows.length;i++) 
{ 

if (newRows+.className && (newRows+.className.indexOf(
'sortbottom') != -1)) table.tBodies[0].appendChild(newRows+);
}     
// Delete any other arrows there may be showing   var allspans = document.getElementsByTagName(
"span");   

for (var ci=0;ci<allspans.length;ci++) 
{   

if (allspans[ci].className == 
'sortarrow') 
{   

if (getParent(allspans[ci],
"table") == getParent(lnk,
"table")) 
{ 
// in the same table as us?   allspans[ci].innerHTML = 
'   ';   
}   
}   
}     span.innerHTML = ARROW;   
}       function getParent(el, pTagName) 
{   

if (el == 

null) 

return 

null;   

else 

if (el.nodeType == 1 && el.tagName.toLowerCase() == pTagName.toLowerCase())   
// Gecko bug, supposed to be uppercase   

return el;   

else   

return getParent(el.parentNode, pTagName);   
}       function ts_sort_date_JWK(a,b) 
{   
// y2k notes: two digit years less than 50 are treated as 20XX, greater than 50 are treated as 19XX   aa = ts_getInnerText(a.cells[SORT_COLUMN_INDEX]);   bb = ts_getInnerText(b.cells[SORT_COLUMN_INDEX]);   

if (aa.length == 10) 
{   dt1 = aa.substr(6,4)+aa.substr(3,2)+aa.substr(0,2);   
} 

else 

if (aa.length == 8 && parseInt(aa.substr(6,2)) && parseInt(aa.substr(3,2)) && parseInt(aa.substr(0,2)))
{   yr = aa.substr(6,2);   

if (parseInt(yr) < 50) 
{ yr = 
'20'+yr; 
} 

else 
{ yr = 
'19'+yr; 
}   dt1 = yr+aa.substr(3,2)+aa.substr(0,2);   
} 

else 
{   

return ts_sort_default(aa,bb);   
}     

if (bb.length == 10) 
{   dt2 = bb.substr(6,4)+bb.substr(3,2)+bb.substr(0,2);   
} 

else 

if (bb.length == 8 && parseInt(bb.substr(6,2)) && parseInt(bb.substr(3,2)) && parseInt(bb.substr(0,2)))
{   yr = bb.substr(6,2);   

if (parseInt(yr) < 50) 
{ yr = 
'20'+yr; 
} 

else 
{ yr = 
'19'+yr; 
}   dt2 = yr+bb.substr(3,2)+bb.substr(0,2);   
} 

else 
{   

return ts_sort_default(aa,bb);   
}   

if (dt1==dt2) 

return 0;   

if (dt1<dt2) 

return -1;   

return 1;   
}       function ts_sort_date(a,b) 
{   
// y2k notes: two digit years less than 50 are treated as 20XX, greater than 50 are treated as 19XX   aa = ts_getInnerText(a.cells[SORT_COLUMN_INDEX]);   bb = ts_getInnerText(b.cells[SORT_COLUMN_INDEX]);   

if (aa.length == 10) 
{   dt1 = aa.substr(6,4)+aa.substr(3,2)+aa.substr(0,2);   
} 

else 
{   yr = aa.substr(6,2);   

if (parseInt(yr) < 50) 
{ yr = 
'20'+yr; 
} 

else 
{ yr = 
'19'+yr; 
}   dt1 = yr+aa.substr(3,2)+aa.substr(0,2);   
}   

if (bb.length == 10) 
{   dt2 = bb.substr(6,4)+bb.substr(3,2)+bb.substr(0,2);   
} 

else 
{   yr = bb.substr(6,2);   

if (parseInt(yr) < 50) 
{ yr = 
'20'+yr; 
} 

else 
{ yr = 
'19'+yr; 
}   dt2 = yr+bb.substr(3,2)+bb.substr(0,2);   
}   

if (dt1==dt2) 

return 0;   

if (dt1<dt2) 

return -1;   

return 1;   
}       function ts_sort_currency(a,b) 
{   aa = ts_getInnerText(a.cells[SORT_COLUMN_INDEX]).replace(/[^0-9.]/g,
'');   bb = ts_getInnerText(b.cells[SORT_COLUMN_INDEX]).replace(/[^0-9.]/g,
'');   

return parseFloat(aa) - parseFloat(bb);   
}       function ts_sort_numeric(a,b) 
{   aa = parseFloat(ts_getInnerText(a.cells[SORT_COLUMN_INDEX]));   

if (isNaN(aa)) aa = 0;   bb = parseFloat(ts_getInnerText(b.cells[SORT_COLUMN_INDEX]));   

if (isNaN(bb)) bb = 0;   

return aa-bb;   
}       function ts_sort_caseinsensitive(a,b) 
{   aa = ts_getInnerText(a.cells[SORT_COLUMN_INDEX]).toLowerCase();   bb = ts_getInnerText(b.cells[SORT_COLUMN_INDEX]).toLowerCase();   

if (aa==bb) 

return 0;   

if (aa<bb) 

return -1;   

return 1;   
}       function ts_sort_default(a,b) 
{   aa = ts_getInnerText(a.cells[SORT_COLUMN_INDEX]);   bb = ts_getInnerText(b.cells[SORT_COLUMN_INDEX]);   

if (aa==bb) 

return 0;   

if (aa<bb) 

return -1;   

return 1;   
}           function addEvent(elm, evType, fn, useCapture)   
// addEvent and removeEvent   
// cross-browser event handling for IE5+,  NS6 and Mozilla   
// By Scott Andrew   
{   

if (elm.addEventListener)
{   elm.addEventListener(evType, fn, useCapture);   

return 

true;   
} 

else 

if (elm.attachEvent)
{   var r = elm.attachEvent(
"on"+evType, fn);   

return r;   
} 

else 
{   alert(
"Handler could not be removed");   
}   
}   </script>

You can filter it if you want… Let me know what you think…

Ben

(imported comment written by abrice)

Super!! thanks for your help, this is great. Now how can I schedule this to be emailed in CSV format? I saw another post to automate the CSV creation http://forum.bigfix.com/viewtopic.php?id=444 which I added the functions but I’m still not given the option to save as a CSV format.