I'm attempting to read a spreadsheet that has predefined charts on multiple tabs using cfspreadsheet, but when it comes to processing the data, I get variable is undefined.
I've used the example from Adobe - http://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/WSc3ff6d0ea77859461172e0811cbec17cba-7f87.html
I've also looked at other examples, but those examples use a combination of cfspreadsheet and poi or java and I would prefer to only use cfspreadsheet if possible. Any idea looking at my code below where the problem is coming from? Thanks.
<cfcontent type="application/vnd.ms-excel" reset="Yes">
<cfquery name="GetData" datasource="#request.dsn#">
SELECT *
FROM v_Occurrences
</cfquery>
<cfset strFileName = "OccurrenceData" & "#now().getTime()#" & "#UserID#">
<!---
<cfdump var="#GetData#">
--->
<cfset filepath = "file:///...OccurenceData.xls">
<!--- Write the two sheets to a single file --->
<cfspreadsheet
action ="read"
columnnames = "Occurence_Date,Full_Name_Client"
columns = "2"
excludeHeaderRow = "false"
headerrow = "1"
query="GetData"
rows = "2"
src ="#filepath#">
<cfscript>
OccurrenceData = SpreadsheetNew("Data");
Month = SpreadsheetNew("Month");
Person = SpreadsheetNew("Person");
SpreadsheetAddRows(occurrencedata,getdata);
</cfscript>
<!--- Write the two sheets to a single file --->
<cfspreadsheet
action="write"
filename="#filepath#"
name="OccurrenceData"
overwrite="true"
sheetname="Data" >
<cfspreadsheet
action="Update"
filename="#filepath#"
name="Month"
sheetname="Month">
<cfspreadsheet
action="Update"
filename="#filepath#"
name="Person"
sheetname="Person" >
<cfspreadsheet
action="read"
src="#filepath#"
sheetname="occurrencedata"
query="GetData">
Here's where the error occurs: variable Occurrence_Data is undefined
<cfscript>
SpreadsheetAddRow(OccurrenceData,"Date,Name",1,1);
SpreadsheetAddRow(OccurrenceData,
"#Dateformat(Occurrence_Date,'mm/dd/yyyy')#,#Full_Name_Client#",
2,1,true);
</cfscript>
<cfspreadsheet
action="write"
autosize="true"
filename="#strFileName#.xls"
overwrite="true"
password="password"
query="GetData"
sheetname="Data" >
Problem number 1. This is probably doing more harm than good.
<cfcontent type="application/vnd.ms-excel" reset="Yes">
Problem number 2. If you want to write two sheets to a single file, you don't do this:
OccurrenceData = SpreadsheetNew("Data");
Month = SpreadsheetNew("Month");
You do something like this:
OccurrenceData = SpreadsheetNew("Data");
// do stuff with this sheet
SpreadsheetCreateSheet(OccurrenceData, "Month");
SpreadSheetSetActiveSheetNumber(OccurrenceData, 2);
// do stuff with this sheet
SpreadSheetWrite(OccurrenceData, whateverYourFileNameIs);
I also suggest that you do one thing at a time. Write a bit of code, run it, and look at the results. Then add a bit more code, run it, and look at the results. This will help you isolate the code that causes the error.
I have excel file that can contain commas in some fields. This can cause problem if I want to use cfspreadsheet to convert my file to csv. I was wondering if there is the way to replace or convert all commas with the \. After I replace all commas then I will be able to use cfspreadsheet to create csv. Here is my code how I read my file:
<cfspreadsheet action = "read" format="csv" src="filePath\myFile.xlsx" name="csvvar">
If anyone can help with this problem please let me know. Thank you.
Convert from Excel to query. Then, in the cell data of each row, replace "," by "\". Something like this
<cfspreadsheet
action = "read"
src="filePath\myFile.xlsx"
query="excelquery"
sheet="1">
<!--- Create CSV file in current directory--->
<cffile action="write" file="#expandpath('result.csv')#" output="">
<cfset columns = arraynew(1)>
<!--- Store the list of column names as an array --->
<cfset columns = listToArray(excelquery.ColumnList)>
<cfoutput query="excelquery">
<cfset rowList = "">
<cfloop from="1" to="#arraylen(columns)#" index="n">
<cfset colName = columns[n]>
<cfset cellData = evaluate("#colName#[currentrow]")>
<!--- Replace , by \ in each cell --->
<cfset cellData = replace(cellData, ",", "\", "all")>
<!--- Comma-separated row data --->
<cfset rowList = listAppend(rowList,cellData)>
</cfloop>
<!--- Place a carriage-return at the end of the row --->
<cfset rowList = rowList & '<br>'>
<!--- Append row to CSV file --->
<cffile action="append" file="#expandpath('result.csv')#" output="#rowList#" >
</cfoutput>
I have a request from a client to generate an Excel spreadsheet from a query. I have the query kicking out the fields and I can generate the Excel file without a hitch. The problem comes when the client takes that Excel file and then tries to manipulate it.
The majority of the trouble comes from fields that should be marked as currency or dates. I am, with some struggle, able to generate a "real" date field. Before this Excel was not sorting the dates properly. I was able to call an Excel formula by using the code below. DateValue forces Excel to acknowledge this as a real date field. However, this fails when this file is manipulated through Excel.
<cfset SpreadsheetSetCellFormula(s
,"DATEVALUE(#Chr(34)##Replacement_ETD##Chr(34)#)"
, therow
, 9)>
The next problem is the currency field. I can't get Excel to acknowledge the values as a currency. It always comes up custom. When this is set, the SUM function won't work in Excel. You can add the fields individually like A1+B1+C1 = TOTAL. However, this won't be helpful when there are 200 rows.
I was able to get a suggestion from another CF programmer who had a similar situation. He generated the Excel file first with the proper headings and set the columns to their proper fields such as date and currency, etc.
The next step would be to fill in the fields row by row and they should be properly formatted.
Code:
<cfset filename = expandPath("./reports/arrivals.xlsx")>
<cfspreadsheet action="read" src = "#filename#" name = "s" >
<cfset therow = 0>
<cfoutput query="myExcel" startrow="1">
<cfset therow = myExcel.currentrow + 1>
<cfset SpreadsheetSetCellValue(s, Incumbent, therow, 1)>
<cfset SpreadsheetSetCellValue(s, Section, therow, 2)>
<cfset SpreadsheetSetCellValue(s, Position_Number, therow, 3)>
<cfset SpreadsheetSetCellValue(s, Position_Title, therow, 4)>
<cfset SpreadsheetSetCellValue(s, Incumbent_Emplyment_Type, therow, 5)>
<cfset SpreadsheetSetCellValue(s, Incumbent_ETD, therow, 6)>
<cfset SpreadsheetSetCellValue(s, Tour_Comments, therow, 7)>
<cfset SpreadsheetSetCellValue(s, Replacement, therow, 8)>
<cfset SpreadsheetSetCellValue(s, Replacement_ETA, therow, 9)>
</cfoutput>
<cfheader name="content-disposition" value="attachment; filename=Departures_(#DateFormat(now(),'mmddyy')#).xls">
<cfcontent type="application/msexcel" variable="#spreadsheetReadBinary(s)#" reset="true">
The data in the cells has already been properly formatted. When this file is generated and streamed to the user the columns are not formatted as expected.
Does anyone else know if this method will work or have a better suggestion on getting CF to generate a proper date and currency field for Excel to acknowledge?
Adobe ColdFusion v10 running on RHEL 5.
Per request here is some code using queryNew that will generate code dates and currency.
Step one: I created an Excel file with the first row frozen and it has the column header. Column one has been designated as the date the format is long date - mm/dd/yyy; Column two is Dollar which as been set to currency.
I read that file then fill in the rows and stream the file to the user for download.
<cfset filename = expandPath("./reports/Test.xlsx")>
<cfspreadsheet action="read" src = "#filename#" name = "s" >
<cfset myQuery = QueryNew("MyDate, Dollar", "Date, Decimal")>
<cfset newRow = QueryAddRow(MyQuery, 5)>
<cfset temp = QuerySetCell(myQuery, "MyDate", "03-11-2000", 1)>
<cfset temp = QuerySetCell(myQuery, "Dollar", "403.45", 1)>
<cfset temp = QuerySetCell(myQuery, "MyDate", "01-01-2009", 2)>
<cfset temp = QuerySetCell(myQuery, "Dollar", "603.22", 2)>
<cfset temp = QuerySetCell(myQuery, "MyDate", "09-21-2013", 3)>
<cfset temp = QuerySetCell(myQuery, "Dollar", "103.55", 3)>
<cfset temp = QuerySetCell(myQuery, "MyDate", "01-15-2005", 4)>
<cfset temp = QuerySetCell(myQuery, "Dollar", "3.33", 4)>
<cfset temp = QuerySetCell(myQuery, "MyDate", "07-22-2003", 5)>
<cfset temp = QuerySetCell(myQuery, "Dollar", "13.75", 5)>
<cfset therow = 0>
<cfoutput query="myQuery" startrow="1">
<cfset therow = myQuery.currentrow + 1>
<cfset SpreadsheetSetCellValue(s, DateFormat(MyDate, 'mm/dd/yyyy'), therow, 1)>
<cfset SpreadsheetSetCellValue(s, Dollar, therow, 2)>
#myQuery.currentrow# <br>
#myQuery.MyDate# <br>
#myQuery.Dollar# <br>
</cfoutput>
<cfheader name="content-disposition" value="attachment;
filename=Departures_(#DateFormat(now(),'mmddyy')#).xls">
<cfcontent type="application/msexcel" variable="#spreadsheetReadBinary(s)#" reset="true">
You can open the file in MS Excel or in Google Sheets. Test one, with the first row frozen, we should be able to sort on the date field. My results are: The dates are not being sorted properly. On column 2 with the currency, if we try to do a SUM that does work! This had not worked before but it does now.
Also, when I try to open the file I am given the warning that this file is corrupt and Excel will try to open it. I get no such warning on Google Sheets.
CF can be a bit quirky when working with date cells. Excel is pretty good about guessing the correct cell type when a value is entered manually. However, it is a little trickier with CF. Since CF is relatively typeless, it does not always match up values and cell types correctly. Using functions that utilize a query object, instead of SpreadsheetSetCellValue(), usually produces better results. Most likely because query objects contains both values and data types. Though as of CF11, SpreadsheetSetCellValue supports a new data parameter, which allows you to specify both the value and cell data type. Since you are using CF10, try using SpreadsheetAddRows to populate the values instead.
Regarding, the warning that the file is corrupt, it is caused by the fact that the actual file content and the file extension in the download code do not match. The code is reading in an .xlsx file, but the download claims it is an .xls (application/msexcel) file. To get rid of the error, make sure the two match.
Here is a working example tested with CF11
<!---
Test.xlsx contains two columns, with headers on row 1
- Column A format: *m/d/yyyy
- Column B format: number with 2 decimal places
--->
<cfspreadsheet action="read" src="c:/temp/Test.xlsx" name="sheet" >
<cfset myQuery = QueryNew("")>
<cfset QueryAddColumn(MyQuery, "Dollar", "Decimal", [ 403.45, 703.22, 103.55, 3.33, 13.75] )>
<cfset QueryAddColumn(MyQuery, "MyDate", "date", [ parseDateTime("2000-03-11", "yyyy-mm-dd")
, parseDateTime("2009-01-01", "yyyy-mm-dd")
, parseDateTime("2013-09-21", "yyyy-mm-dd")
, parseDateTime("2005-01-15", "yyyy-mm-dd")
, parseDateTime("2003-07-22", "yyyy-mm-dd")] ) >
<cfset spreadsheetAddRows(sheet, myQuery)>
<cfset spreadsheetFormatColumn(sheet, {dataFormat="m/d/yy"}, 1)>
<cfset spreadsheetFormatColumn(sheet, {dataFormat="##,####0.00"}, 2)>
<cfheader name="content-disposition" value="attachment; filename=Departures_(#DateFormat(now(),'mmddyy')#).xlsx">
<cfcontent type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" variable="#spreadsheetReadBinary(sheet)#" reset="true">
I need a way to find the difference between two strings in a Windows application using VBScript. One of the strings is known but the second one is completely unknown during coding. I know there are functions like StrCompare, InStr etc. but these require you to know the second string also during coding.
Explanation:
There is a text box in the screen and there are several buttons in the same screen. As and when the buttons are clicked, the text in the text box changes depending on the button clicked. Is there a way to find the changes made to the text after the button is clicked ? Basically I need to get the text entered due to the button click. Is there a simple way to do this or it requires complex coding ?
Thanks in Advance.
It depends on your application and the format of the new string.
If you need to find the text appended to the original string, you could take the new text and simply replace the first occurrence of the original string with an empty string:
Dim strOld, strNew, strDiff
strOld = "Apple"
strNew = "Apple, Orange"
strDiff = Replace(strNew, strOld, "", 1, 1)
WScript.Echo strDiff
Sample output:
, Orange
Or if you need to get the appended text without the preceding comma, you could use something like this:
strDiff = Replace(strNew, strOld + ", ", "", 1, 1)
To access (read/write) the content of a HTML text input you need to get the HTML element (document.all.<Name/Id> or document.getElementById(<Name/Id>) and its .value; as in this demo:
<html>
<head>
<Title>readtext</Title>
<hta:application id="readtext" scroll = "no">
<script type="text/vbscript">
Function Change()
document.all.txtDemo.value = "Changed Value"
End Function
Function Check()
Dim txtDemo : Set txtDemo = document.getElementById("txtDemo")
Dim sDemo : sDemo = txtDemo.value
Select Case LCase(Trim(sDemo))
Case "initial value"
MsgBox "still: " & sDemo
Case "changed value"
MsgBox "now: " & sDemo
Case Else
MsgBox "surpise: " & sDemo
End Select
End Function
</script>
</head>
<body>
<input type="text" id="txtDemo" value="Initial Value" />
<hr />
<input type="button" value="Change" onclick="Change" />
<input type="button" value="Check" onclick="Check" />
</body>
</html>
I am using a cfloop to generate the titles of a bunch of variables.
Problem is on output I just get the actual variable name ie #qQuery.varName# instead of its value ie "Item Name".
Heres a quick taste of my code:
<cfloop query="qQuery">
<cfloop query="qTest">
<cfset varTest = "qQuery." & varName>
<cfoutput>#varTest#</cfoutput>
</cfloop>
</cfloop>
Thanks :)
Try something like this:
<cfset vartest = qQuery[varName]>