In Coldfusion, how do I increase a variable number by 1 for 5 loops?
I tried the following:
<cfset num = 19001>
<cfoutput>
<cfloop index="i" from="#num#" to="5">
#num#
</cfloop>
</cfoutput>
But this is not working.
You can do it like this:
<cfset num = 19001>
<cfoutput>
<cfloop index="i" from="#num#" to="#num+5#">
#i#
</cfloop>
</cfoutput>
You could simply loop from 1 to 5 and add 1 to your base number each time. Then your starting number can be anything and you don't need to calculate your end value ahead of time.
<cfset num = 19001>
<cfoutput>
<cfloop index="i" from="1" to="5">
<cfset num = num + 1>
#num#
</cfloop>
</cfoutput>
Related
I have problem for getting and working on a structure containing dynamic variable names. I have a structure cfStruct which contains another structure EMAILS. In the last structure the maximum of items is 4
Here my structure for EMAILS
EMAILS":{"1":"mail1#test.com","2":"mail2#test.net","3":"mail3#test.fr"}
I try to create one variable for each item of this structure if it exists by doing that. Nevertheless it doesn't work:
<cfif IsDefined("cfStruct.EMAILS")>
<cfloop from="1" to="5" index="i">
<cfif StructKeyExists( cfStruct.EMAILS, '#i#' ) >
<cfset setVariable( "EMAIL_#i#", "#cfStruct.EMAILS.i#" >
<cfelse>
<cfset setVariable( "EMAIL_#i#", '') >
</cfif>
</cfloop>
<cfelse>
Could you please help me to solve the problem?
Regards,
I believe the cleanest was to write this is:
<cfloop from="1" to="5" index="i">
<cfif StructKeyExists( cfStruct.EMAILS, i ) >
<cfset variables["EMAIL_#i#"] = cfStruct.EMAILS[i] >
<cfelse>
<cfset variables["EMAIL_#i#"] = '' >
</cfif>
</cfloop>
For the following reasons:
No unnecessary string expressions. Every time you do '#i#' you're telling CF to parse the string, evaluate the expressions within it, and return a new string in place of this one..
Explicit is better than implicit, using variables["EMAIL_#i#"] tells you exactly where you've put the variable you're creating so when you come to re-read months later it's crystal clear what's going on.
Bonus
If you change your loop to <cfloop from="1" to="#structCount(cfStruct.EMAILS)#" index="i"> then your code won't create more variables than needed (if this effect is desired) and could scale up to any number struct values.
I solved the problem it was a syntax problem:
<cfloop from="1" to="5" index="i">
<cfif StructKeyExists( cfStruct.EMAILS, '#i#' ) >
<cfset setVariable( "EMAIL_#i#", "#cfStruct.EMAILS[i]#") >
<cfelse>
<cfset setVariable( "EMAIL_#i#", '') >
</cfif>
</cfloop>
Strictly speaking, you should use cfStruct.EMAILS["#i#"] instead of "#cfStruct.EMAILS[i]#". That is,
<cfloop from="1" to="5" index="i">
<cfif StructKeyExists( cfStruct.EMAILS, "#i#" ) >
<cfset setVariable( "EMAIL_#i#", cfStruct.EMAILS["#i#"]) >
<cfelse>
<cfset setVariable( "EMAIL_#i#", '') >
</cfif>
</cfloop>
I am getting an error after upgrade from coldfusionOX to coldfusion 10.
Error Occurred While Processing Request Complex object types cannot be
converted to simple values.
The expression has requested a variable or an intermediate expression
result as a simple value. However, the result cannot be converted to a
simple value. Simple values are strings, numbers, boolean values, and
date/time values. Queries, arrays, and COM objects are examples of
complex values. The most likely cause of the error is that you tried
to use a complex value as a simple one. For example, you tried to use
a query variable in a cfif tag.
It occurs at line " cfloop index="local.thisRight" list="#rights#" ". It seems like ColdFusion does not like the "rights" here.
Anyone can give me some help? Thanks so much.
<cfif local.profile.rights.profile.self is not "">
<cfquery name="local.getAffiliations" datasource="#Request.readerDSN#">
SELECT tblPersonsToAffiliations.affiliationID, tblPersonsToAffiliations.rights, tblAffiliations.affiliationType, tblPersonsToAffiliations.relationshipType
FROM tblPersonsToAffiliations INNER JOIN tblAffiliations
ON tblPersonsToAffiliations.affiliationID = tblAffiliations.affiliationID
WHERE tblPersonsToAffiliations.personID IN (#local.profile.rights.profile.self#)
AND (tblPersonsToAffiliations.archived IS NULL
OR tblPersonsToAffiliations.archived = '')
</cfquery>
<cfif local.getAffiliations.recordCount is not 0>
<cfloop query="local.getAffiliations">
<cfif local.getAffiliations.relationshipType is "interested">
<cfset local.thisRelationshipType = "provisionalMember">
<cfif IsDefined("local.profile.rights.#affiliationType#.#local.thisRelationshipType#")>
<cfset local.profile.rights[affiliationType][local.thisRelationshipType] = ListAppend(local.profile.rights[affiliationType][local.thisRelationshipType], affiliationID)>
<cfelse>
<cfset local.profile.rights[affiliationType][thisRelationshipType] = affiliationID>
</cfif>
<cfelse>
<cfset local.thisRelationshipType = "fullMember">
<cfif IsDefined("local.profile.rights.#affiliationType#.#local.thisRelationshipType#")>
<cfset local.profile.rights[affiliationType][local.thisRelationshipType] = ListAppend(local.profile.rights[affiliationType][local.thisRelationshipType], affiliationID)>
<cfelse>
<cfset local.profile.rights[affiliationType][local.thisRelationshipType] = affiliationID>
</cfif>
<cfif isNull(rights)>
<cfelse>
<cfloop index="local.thisRight" list="#rights#" >
<cfif IsDefined("local.profile.rights.#affiliationType#.#local.thisRight#")>
<cfset local.profile.rights[affiliationType][local.thisRight] = ListAppend(local.profile.rights[affiliationType][local.thisRight], affiliationID)>
<cfelse>
<cfset local.profile.rights[affiliationType][local.thisRight] = affiliationID>
</cfif>
</cfloop>
</cfif>
</cfif>
</cfloop>
</cfif>
</cfif>
A bit earlier in your code you do this:
<cfif local.getAffiliations.relationshipType is "interested">
I think you need the same query name prefix in front of "rights" that is used when evaluating "relationshipType".
Try this:
#local.getAffiliations.rights#
HTH!
I am betting it is failing on this line:
<cfloop index="local.thisRight" list="rights" >
You are attempting to use the string "rights" as a list. My first reaction would be that you need to make that:
<cfloop index="local.thisRight" list="#rights#" >
Using the following query, I am trying to do a simple case here when the first record it encounters it should basically add "AND" and for the remaining conditions, I want to add OR
Here is my try
<cfif isDefined('age') and len(trim(age)) and age neq '-1'>
<cfset age = trim(htmlEditFormat(lcase(age)))>
<cfloop list="#age#" index="k">
or age between #ListFirst(k,'-')# and #ListLast(k,'-')#
</cfloop>
</cfif>
trying to make it work like this
and (age between 18 and 20
or age between 20 and 25
or age between 25 and 30)
I am not getting where I should add a condition to add parenthesis and the AND operator.
You could do something as similar as adding a false statement and then looping through everything else as needed
<cfif isDefined('age') and len(trim(age)) and age neq '-1'>
<cfset age = trim(htmlEditFormat(lcase(age)))>
AND (1 = 2 --always returns false
<cfloop list="#age#" index="k">
OR age between #ListFirst(k,'-')# and #ListLast(k,'-')#
</cfloop>
)
</cfif>
This is what you were trying to do
<cfif isDefined('age') and len(trim(age)) and age neq '-1'>
<cfset age = trim(htmlEditFormat(lcase(age)))>
AND (
<cfloop list="#age#" index="k">
<cfif listFirst(age) NEQ k> OR </cfif> --if it's not the first iteration, add the OR
age between #ListFirst(k,'-')# and #ListLast(k,'-')#
</cfloop>
)
</cfif>
An alternative that doesn't require an if block and would work for any type of loop:
<cfif isDefined('age') and len(trim(age)) and age neq '-1'>
<cfset age = trim(htmlEditFormat(lcase(age)))>
<cfset expressionSeparator = "">
AND (
<cfloop list="#age#" index="k">
#expressionSeparator#
age between #ListFirst(k,'-')# and #ListLast(k,'-')#
<cfset expressionSeparator = " or ">
</cfloop>
)
</cfif>
I have a variable named #cfData# which contains an array of structures. As it's clear from the image, for 1st structure array there are 6 keys and for 2nd, only two keys,viz date and open.
If I run a common loop, to go through each and every key, I will get an error at second array element. So the following only works when all the keys are present in the structure:
<cfset blockedtotal = 0 />
<cfset bouncetotal = 0 />
<cfset blocked = 0/>
<cfset datetotal = 0 />
<cfloop array = #cfData# index = "i">
<cfset blockedtotal += i.blocked />
<cfset bouncetotal += i.bounce />
</cfloop>
After reading online, I got an idea of using StructKeyExists where I think I can proceed in the following way:
<cfif structKeyExists(cfData,"bounce")>
<cfoutput>Bounce:#cfData.bounce#"/></cfoutput>
<cfelse>
<cfoutput> Bounce : [none]<br/></cfoutput>
</cfif>
But I am wondering, where exactly should I insert the above code inside the cfloop? Please advise if my approach is wrong.
Update:
Thanks guys. I got it running by using the following code based on the answers and it's running fine:
<cfloop array="#cfData#" index="i">
<cfif structKeyExists(i, "date")>
<cfset counter++>
<cfoutput>#counter#</cfoutput> Date is: <cfoutput> #i.date#</cfoutput> <br/>
</cfif>
</cfloop>
you don't need a "common loop". You can loop through each struct with
<cfloop array="#cfData#" index="i">
<cfloop collection="#i#" item="key">
struct with key '#key#' has data: #i[key]#
</cfloop>
</cfloop>
Of, if you need to decide if the struct has certain key, do something:
<cfloop array="#cfData#" index="i">
<cfif structKeyExists(i, "someKey")>
<cfset counter++>
</cfif>
</cfloop>
Making the array:
<cfset tempArr = DeserializeJSON(URL.data) />
<cfset temp1 = "" />
<cfset temp2 = "" />
<cfset selectList1 = "" />
<cfset selectList2 = "" />
<cfloop array=#tempArr# index="i">
<cfset temp1 = GetToken(i,1,":")>
<cfset temp2 = GetToken(i,2,":")>
<cfset selectList1 = listAppend(selectList1, temp1)>
<cfset selectList2 = listAppend(selectList2, temp2)>
</cfloop>
Looping through it??:
<cfquery name="sample" datasource="database">
SELECT *
FROM table
WHERE
<cfloop from="1" to="#listLen(selectList1)#" index="i"/>
#ListGetAt(selectList1, i)# = <cfqueryparam value="#ListGetAt(selectList2)#" />
</cfloop>
<cfif i neq listLen(#selectList1#)>
AND
</cfif>
</cfquery>
My intention is to search dynamically in a table based on the array that was received from the javascript page. The data comes in this form -> columnName:searchBy. ie, a sample piece would be name:Jim. I would like to build in dynamic code that would allow me to search by different columns but I can't get my loop to work. I get this error if it helps:
(Invalid CFML construct found on line 20 at column 59.)
which is this line:
<cfloop from="1" to="#listLen(selectList1)#" index="i" />
Kyle's answer is 100% correct, but here's a better solution. Using lists is a very inefficient process (see below) and using listGetAt will only anger future programmers. You can use an array to house the data and use a default WHERE statement to simplify your looping.
<cfset tempArr = DeserializeJSON(URL.data) />
<cfset temp1 = "" />
<cfset temp2 = "" />
<cfset selectList1 = [] />
<cfset selectList2 = [] />
<cfloop array=#tempArr# index="i">
<cfset temp1 = GetToken(i,1,":")>
<cfset temp2 = GetToken(i,2,":")>
<cfset arrayAppend(selectList1, temp1)>
<cfset arrayAppend(selectList2, temp2)>
</cfloop>
<cfif NOT arrayIsEmpty(tempArr)>
<cfquery name="sample" datasource="database">
SELECT column1, column2, column3
FROM table
WHERE 1 = 1
<cfloop from="1" to="#listLen(selectList1)#" index="i"/>
AND #selectList1[i]# = <cfqueryparam value="#selectList2[i]#" />
</cfloop>
</cfquery>
</cfif>
When you append to a list a new string is created in memory that combines the two previous string and the previous string is deleted. This is definitely premature optimization, but it's still a good practice to avoid using lists especially when you need to access elements in them.
I think your problem might be that the cfloop tag is self closing. Try this instead:
<cfloop from="1" to="#listLen(selectList1)#" index="i">
list attribute can be used in <cfloop>.
<cfloop list="#selectList1#" index="i">
#i# <!--- list element can be processed here with variable name #i# --->
</cfloop>