• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 926
  • Last Modified:

ColdFusion How can I add a calculated field to my excel export function?

I have two fields in my excel export:
Qty Ordered & Qty Received

How can I automatically create another column "Amount Missing" with the formula:
Qty Ordered minus Qty Received = Amount Missing

Excel Export Code:

<cfif structKeyExists(FORM, "export") AND structKeyExists(VARIABLES, "Results")>

	<cfset sObj = SpreadsheetNew("Ship=#discipline1#")>
     <!--- create query param strings ----> 
    <cfset querySummary = "Ship = #discipline1#, Project = #discipline4#, Contract = #discipline7#, Records Found ("& Results.RecordCount &")">
    <cfset recordsSummary = "("& Results.RecordCount &") Records Found">

    <!--- add query parmas in 1st row and center align --->
    <cfset columnsInQuery = listLen(results.columnList)>
    <cfset SpreadsheetMergeCells(sObj, 1, 1, 1, columnsInQuery)>
    <cfset SpreadSheetSetCellValue(sObj, querySummary, 1, 1)>
    <cfset SpreadsheetFormatRow(sObj, {alignment="center"}, 1)> 

    <!--- add record count in 2nd row and center align --->
   <!--- <cfset SpreadsheetMergeCells(sObj, 2, 2, 1, columnsInQuery)>
    <cfset SpreadSheetSetCellValue(sObj, recordsSummary, 2, 1)>
    <cfset SpreadsheetFormatRow(sObj, {alignment="center"}, 2)> --->
  	<!--- Create header row --->
    <!--- <cfset spreadsheetSetHeader(SObj,"","Material Status Report","")>--->
	<cfset SpreadsheetAddRow(sObj, "Num,ISP,QTY Ordered,QTY REC,I,Part Description,S,Q,Num,,DO,hip,ject")>
      <cfset SpreadsheetFormatRows(sObj, {bold=TRUE,fgcolor="grey_25_percent", alignment="center"},1 )> 
      <cfset SpreadsheetFormatRow(sObj, {bold=TRUE,fgcolor="light_yellow", alignment="center"},2 )> 
   <cfset SpreadsheetFormatColumn(sObj, {alignment="right", dataformat="mm/dd/yyyy"}, 15)>
     <cfset SpreadsheetAddRows(sObj, Results)>
     <cfset SpreadsheetFormatColumns(sObj, {fontsize="14",verticalalignment = "vertical_center",leftborder="thin",rightborder="thin",bottomborder="thin"},"1-13")>
   
   <cfset SpreadsheetFormatColumns(sObj, {alignment="center"}, "1-4")>
   
   <cfset SpreadSheetSetColumnWidth(sObj, 3, 3)> 
<cfset SpreadsheetFormatCell(sObj, {textwrap=true,verticalalignment = "vertical_justify"}, 2, 3)>
<cfset cellValue = "QTY"& chr(10) & "REQ"& chr(10) >
<cfset SpreadsheetSetCellValue(sObj, cellValue, 2, 3)>
   
    <cfset SpreadSheetSetColumnWidth(sObj, 3, 4)> 
<cfset SpreadsheetFormatCell(sObj, {textwrap=true,verticalalignment = "vertical_justify"}, 2, 4)>
<cfset cellValue = "QTY"& chr(10) & "REC"& chr(10) >
<cfset SpreadsheetSetCellValue(sObj, cellValue, 2, 4)>
   
     <cfset SpreadsheetSetRowHeight(sObj,1, (40))>
     
     <cfset SpreadsheetFormatCell(sObj, {textwrap=true}, 2, 3)>
  <cfset SpreadSheetSetColumnWidth(sObj, 3, 3)>
     
     <cfset maxRow = Results.recordCount +  (2)>
     <cfloop from="1" to="#maxRow#" index="rowNum">
         <cfset SpreadsheetSetRowHeight(sObj, rowNum, (40))>
     </cfloop>
     
      <cfset SpreadsheetFormatRow(sObj, {topborder="thin"},3)>
     
   <cfset SpreadsheetFormatColumn(sObj, {alignment="left", dataformat="mm/dd/yyyy"}, 14)>
     <!--- file name MUST be unique --->
     <cfset saveToFile = "C:\Report#createUUID()#.xls">
     
     <!--- get the underlying poi sheet --->
     <cfset poiSheet = sObj.getWorkBook().getSheet("Ship=#discipline1#")>
     <cfset ps = poiSheet.getPrintSetup()>
     <cfset ps.setLandscape(true)>
     <cfset poiSheet.setAutobreaks(true)>
     
     
    <!--- Fit to an 8" wide page...for a small level of auto formatting pre-Excel... this could be made dynamic for different paper sizes--->

   <cfset ps.setFitHeight(javacast("short", 200))>
   <cfset ps.setFitWidth(javacast("short", 1))>
   <cfset poisheet.setMargin(POISheet.TopMargin,.10)>
   <cfset poisheet.setMargin(POISheet.BottomMargin,.10)>
   <cfset poisheet.setMargin(POISheet.LeftMargin, .10)>
   <cfset poisheet.setMargin(POISheet.RightMargin,.10)>

     
     
     
     <cfspreadsheet action="write" name="sObj" filename="#saveToFile#" overwrite="true">

     <cfheader name="Content-Disposition" value="inline; filename=Report.xls">
     <cfcontent type="application/excel" file="#saveToFile#" deletefile="yes">
     <!---- we're finished so exit --->
     <cfabort />
</cfif>

Open in new window

0
DJPr0
Asked:
DJPr0
  • 5
  • 4
2 Solutions
 
Rodrigo MuneraSr. Software EngineerCommented:
To create the new column, you have to create it into your original query, or in the header row if the column will be at the end of the data.

Once you have the column, and you have populated your entire spreadsheet with your data, You have to put the formula in each cell.

In my code below I'm adding 2 formulas to 2 separate rows, I start from the second row, so my code will skip the header row and start inserting the formula in the second row of the spreadsheet, and I'm setting the "to" field to record count of my query +1 (to account for the header row being skipped)

In the code below "qReturn" is my query object with the data that was passed to the spreadsheet, "sprObj" is the spreadsheet object, my formulas are "IF(H[row]=0,0,I[row]/H[row])" and "IF(H[row]=0,0,J[row]/H[row])".

The syntax for entering a function into a spreadsheet is https://wikidocs.adobe.com/wiki/display/coldfusionen/SpreadsheetSetCellFormula

<cfloop from="2" to="#qReturn.recordcount+1#" index="i">
	<cfset SpreadSheetSetCellFormula(sprObj,"IF(H#i#=0,0,I#i#/H#i#)",i,12)>
	<cfset SpreadSheetSetCellFormula(sprObj,"IF(H#i#=0,0,J#i#/H#i#)",i,13)>
</cfloop>

Open in new window

0
 
Rodrigo MuneraSr. Software EngineerCommented:
I use that loop after I've populated my spreadsheet object with
SpreadsheetAddRows(sprObj,qReturn);

Open in new window

0
 
DJPr0Author Commented:
Thanks for the reply Rodrigo.

I need some help with the formula:

If column 3 and 4 has a number, perform a minus calculation and output on column 5

Qty Ordered - Qty Received = Qty Missing  (Calculation is performed on each row)
       10                      5                     5
0
Ultimate Tool Kit for Technology Solution Provider

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy now.

 
Rodrigo MuneraSr. Software EngineerCommented:
Excel formulas are based on the rows and columns where your data resides.

For this example, I'm going to assume:
Qty Ordered is on Column A
Qty Received is on Column B
Qty Missing is on Column C (the position of this column is 3)

Your formula in excel "=IF(AND(ISNUMBER(A1),ISNUMBER(B1)),A1-B1,0)"
In Coldfusion you don't use the "=" at the beginning of the formula, so you would put your formula as: "IF(AND(ISNUMBER(A1),ISNUMBER(B1)),A1-B1,0)"
Also, you want to replace the hard-coded rows with variables


<cfloop from="2" to="#qReturn.recordcount+1#" index="i">
	<cfset SpreadSheetSetCellFormula(sprObj,"IF(AND(ISNUMBER(A#i#),ISNUMBER(B#i#)),A#i#-B#i#,0)",i,3)>
</cfloop>

Open in new window

0
 
Rodrigo MuneraSr. Software EngineerCommented:
Just to clarify, the formulas are not being calculated by coldFusion, cold fusion is only putting the formula in your spreadsheet (I'm assuming your user will have excel), and the actual calculation is made by the spreadsheet once it is opened by the user.
0
 
DJPr0Author Commented:
The formula seems to be downloading to the excel sheet ; )

Formula in excel sheet:
=IF(AND(ISNUMBER(C3),ISNUMBER(D3)),C3-D3,)

Problem:
All fields have 0

If I put the cursor in the formula and press enter the formula/calculation works.

I tried saving then opening without success - does something need to trigger the formula when the excel sheet opens?
0
 
Rodrigo MuneraSr. Software EngineerCommented:
Hmm, that seems to be an excel question. In my spreadsheets the formula loads when I open it, but I'm also not using that number of functions. You could try stripping the formula down to just "C[row]-D[row]" and see if that does the trick.
0
 
DJPr0Author Commented:
Yes, If I strip it down it calculates the one with numbers in both cells and gives me an error with no value:

<cfset SpreadSheetSetCellFormula(sObj,"IF(ISNUMBER(C#i#),C#i#-D#i#, )",i,5)>

Strip down version works fine since one column always has a number.
0
 
DJPr0Author Commented:
Thanks for your assistance Rodrigo Munera!
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Ultimate Tool Kit for Technology Solution Provider

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy now.

  • 5
  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now