I have a table in a form with a loop around it that sets an index on all the name fields (form variables) that changes based on user input (user dictates how many tables get built).
Once submitted, I take these variables and create a struct out of it. I know that a query object is already a struct, but I have to have each tables names unique, then put them into a struct which I can then rename to insert into the DB.
My problem is how do I write this correctly and efficiently? I need to have a variable with a nested variable that is my index to make the name unique for each iteration through the loop. I have tried many combinations of pound signs and quotes and can't get it.
If there is a better way to do this I am up for that too!
dot notation
cfset myStruct#i#=StructNew()>
cfset myStruct#i#.ID#i#="#form.myVarA#i##"
cfset myStruct#i#.s1#i#="#form.myVarB#i##"
cfset myStruct#i#.s2#i#="#form.myVarC#i##"
associated array notation
cfset myStruct#i#=StructNew()>
cfset myStruct#i#[ID#i#]="#form.myVarA#i##"
cfset myStruct#i#[s1#i#]="#form.myVarB#i##"
cfset myStruct#i#[s2#i#]="#form.myVarC#i##"
Any help is greatly appreciated.
This is the best reference you'll ever need to understand variables in CFML:
http://www.depressedpress.com/Content/Development/ColdFusion/Guides/Variables/Index.cfm
To answer your question, try this:
<cfset myStruct["#i#"] = structNew() />
<cfset myStruct["#i#"]["ID#i#"] = form["myVarA#i#"] />
<cfset myStruct["#i#"]["s1#i#"] = form["myVarB#i#"] />
This should give you:
myStruct.1.id1 = form.myvarA1
myStruct.1.s11 = form.myvarB1
Related
I am having difficulties trying to use ListAppend.
I have data from a table and this is my code.
<cfquery name="getData" datasource="test">
select * from test;
</cfquery>
Now what I want to do is to make all the values in the column name which I have named it as nm_column into a list using ListAppend.
<cfset dataList = ListAppend('', '#getData.nm_column#')>
<cfoutput>#dataList#</cfoutput>
What this does is that it only shows the 1st value of the nm_colum. I do understand that I am missing the loop part, thats why its only showing me just the 1st value. So how do I loop it and get all the values to it?
I tried this, but it did not work.
<cfset dataList = ListAppend('', '<cfloop query="getData">#getData.nm_column#</cfloop>')>
So can someone please teach me the way to properly write that code?
There's a built in function in ColdFusion that will do this for you.
<cfset dataList = valueList(getData.nm_column)>
As far as the issue with your code, listAppend's first argument is the list you're adding things to. Also, you cannot nest ColdFusion tags like that. The code will not compile.
If you want to loop through something to append to a list, this is what you would do.
<cfset dataList = ''>
<cfloop query="getData">
<cfset dataList = listAppend(dataList, nm_column)>
</cfloop>
This would be terrible for performance though since a string is immutable. If you really needed to add items to a list through a lip I would create an array and then use arrayToList to convert that array to a list.
I'm using a cfspreadsheet read to read a sheet into a query object.
<cfspreadsheet action="read" src="TestExcel.xls" sheet="1" query="spreadsheetData" headerrow="1" excludeHeaderRow="true">
The problem is, some of the headers contain more than one word. So I end up with a query a bit like this:
ID Name Start Date End Date
3 Test 1/1/2009 1/1/2013
17 Test 2 11/11/2010 11/11/2012
If I try to access one of the columns that have a space in the column name, I get an error.
<cfoutput query="spreadsheetData">
#start date#
</cfoutput>
I've tried #[start date]# as well, but that didn't work. I cannot control the format of the excel sheet that I receive. Is there any way to access the multiple-worded-header columns?
When using bracket notation the contents must end up as a string, so:
<cfoutput query="spreadsheetData">
#spreadsheetData['start date'][CurrentRow]#
</cfoutput>
If you don't use quotes, you are passing in a variable, which is done like so:
<cfset ColumnName = 'start date' />
<cfoutput query="spreadsheetData">
#spreadsheetData[ColumnName][CurrentRow]#
</cfoutput>
Note that you must use the query name before the brackets - if you simply write [ColumnName] then this is inline array creation notation, not accessing the variable.
Also, if using this outside of a query loop (i.e. not within cfoutput/cfloop with query attribute), you also need to scope the CurrentRow variable, i.e.
spreadsheetData[ColumnName][spreadsheetData.CurrentRow]
(or provide your own explicit number/variable).
As Leigh notes below, for cfspreadsheet-specific behaviour, you can also specify the columnnames attribute, to rename the column to something directly accessible, e.g.
<cfspreadsheet query=".." columnNames="Foo,Bar,StartDate,Etcetera" ..>
<cfloop query="GET_ALL_STUDENTS>
<cfif #student_id# is NOT NULL>
<!--- do something--->
</cfif>
</cfloop>
Above is how I am looping my cf query which returns null value and I want to check if the student_id is null or not. This is what I have tried and it failed. Can anyone tell me a better way?
You can use your database's ifNull() or the like. However, in ColdFusion, queries are returned as strings. Given your situation, easiest way is to check for a non-empty string:
<cfif len(student_id)>
By the way, you don't need the pound signs inside of an evaluation: only when using a variable as a literal (such as when outputting)
In Adobe ColdFusion 9, you can do:
<cfif IsNull(student_id)>
</cfif>
Or since you're doing the opposite:
<cfif NOT IsNull(student_id)>
</cfif>
It looks like the query is retrieving all of the students and then cfloops over the records to find the student_id fields that are NULL.
It would be more efficient to write a query that specifically queried the records that have student_id IS NULL.
The method of grabbing all the student table records will work great when you have 100 or so students. What happens when it is put into production and there are 25,000 students?
While the java class of CFQuery object (coldfusion.sql.QueryTable) will return empty string for any null value, it's parent class coldfusion.sql.Table is providing a method getField(row, column) to access the query table values directly, which return "undefined" if the value is null. We can make use of the IsNull to identify the "undefined" hence able to detect NULL.
<CFLOOP query="GET_ALL_STUDENTS">
Row = #CurrentRow#
<CFIF IsNull(GET_ALL_STUDENTS.getField(GET_ALL_STUDENTS.CurrentRow, GET_ALL_STUDENTS.findColumn('student_id')))>
[NULL]
<CFELSE>
#GET_ALL_STUDENTS.student_id#
</CFIF>
<br>
</CFLOOP>
Reference: http://laxmanthota.blogspot.com/2010/11/cfquery-and-underlying-java-objects.html
The function for adding a row to a coldfusion spreadsheet is SpreadsheetAddrow which accepts data as "A comma delimited list of cell entries, one per column."
Some of my data has commas within it. How do I escape the commas within my data without escaping the commas in the list?
I am currently creating an array with the contents of the row, then converting it to a list to add to the spreadsheet:
<cfset row = ArrayNew(1)>
<cfloop list="#structKeyList(setRecord.columns)#" index="key">
<cfset ArrayAppend(row, "#Evaluate(key)#")>
</cfloop>
<cfset spreadsheetAddRow(xlsObj, "#ArrayToList(row)#")>
Looks like the ability to specify a different delimiter is not supported yet. Since you are already looping, you may as well skip the array and use SpreadsheetSetCellValue instead. You should be able to eliminate the evaluate() as well.
<cfset cols = structKeyArray(yourStruct) >
<cfloop from="1" to="#arrayLen(cols)#" index="c">
<cfset SpreadsheetSetCellValue(xlsObj, yourStruct[ cols[c] ], lastRow, c)>
</cfloop>
<cfset lastRow++>
...
Update: However, if the base object is a query, not a structure, then it is more efficient to use CfSimplicity's suggestion of SpreadSheetAddRows.
If the data you want to add to the sheet is in a query object (recordset) then the simplest solution is to use SpreadSheetAddRows(), (as opposed to SpreadSheetAddRow - singular).
<cfset SpreadSheetAddRows( xlsObj,query )>
The sheet columns are mapped from the query columns, so commas in the data won't matter.
Even if the data is in another format or you are only adding a single row, converting it to a query object is an effective way of getting round the issue, see http://cfsimplicity.com/30/workaround-for-spreadsheetaddrow-limitation-when-column-values-contain-commas
You can replace the commas with the character "#130;" (see the source: https://www.petefreitag.com/cheatsheets/ascii-codes/), which looks the same as comma but doesn't create any problems.
I'm totally unused to Cold Fusion, I'd like to know how to handle a multiple CFSELECT, in particular how to know how many rows I've selected and taking them one by one.
Actually I've managed to see all the rows togheter:
<!--- page_a.cfm --->
<cfform name="fooform" ........>
<cfselect query="myquery" name="fornitori" multiple="yes"></cfselect>
<!--- page_b.cfm --->
<cfoutput>#form.fornitori#</cfoutput>
And, if it's not too much, I'd like to know why it's not correct to write:
<!--- page_b.cfm --->
<cfoutput>#fooform.fornitori#</cfoutput>
Since it is a multiple selection list, the options you select will be submitted to page_b.cfm as a comma delimited list. This means you can use list functions to calculate the total items selected and cfloop to iterate through the selections individually. Note, when using "multiple" select lists, if you select nothing the form field will not exist.
<cfparam name="form.fornitori" default="">
<cfoutput>
Total Items Selected = <cfoutput>#listLen(form.fornitori)#</cfoutput>
Individual Selections:<br>
<cfloop list="#form.fornitori#" index="theSelection">
#theSelection#<br>
</cfloop>
</cfoutput>
why it's not correct to write ..
Because FORM refers to a special system structure, not the name of your html form (ie fooform). FORM contains any form fields submitted via method=POST.
#myquery.recordcount#
btw, use cfdump to display anything. you see some really interesting stuff (I'm not sure whether recordcount is in there though)
getting to the elements:
<cfoutput query="queryname">#title#<br />#content#</cfoutput>
inside the cfoutput you have access to the variables of an element.
coldfusion 9 help