问题
i created a table using coldfusion lists system, rows are months and the columns are cities, and the variable is the sales, now i need to add to every evaluated sale variable, the list of companies that made these sales, so far there is no problem with writting the sql of this table and the sales, but i cant define-#evaluate# the list of these companies that belongs to each sale in the table, since it is the LIST of companies, not one variable like sale, i hope i made myself clear :) here is my code:
The query with some sets:
<cfset month_list_name = "#message13#,#message2#,#message3#,#message4#,#message5#,#message6#,#message7#,#message8#,#message9#,#message10#,#message11#,#message12#">
<cfset type_index = 'NETTOTAL'>
<cfquery name="GET_CITY" datasource="#DSN#">
SELECT CITY_ID,CITY_NAME FROM SETUP_CITY ORDER BY CITY_NAME
</cfquery>
<cfquery name="GET_COMPANY" datasource="#DSN#">
SELECT COMPANY_ID,FULLNAME FROM COMPANY ORDER BY COMPANY_ID
</cfquery>
<cfset c_index = 'COMPANY_ID'>
<cfset no_cities = 0 />
<cfset cities_list = ''>
<cfset cities_list_name = ''>
<cfset month_list = ''>
<cfoutput query="get_city"><cfset cities_list = listappend(cities_list,city_id)><cfset no_cities ++ /></cfoutput>
<cfoutput query="get_city"><cfset cities_list_name = listappend(cities_list,city_name)></cfoutput>
<cfloop from="1" to="12" index="i"><cfset month_list=listappend(month_list,i)></cfloop>
<cfquery name="GET_SALES_TOTAL" datasource="#dsn#">
SELECT
SUM(NETTOTAL) NETTOTAL,
SC.CITY_ID,
DATEPART(MM,INVOICE_DATE) AY,
C.FULLNAME,
C.COMPANY_ID AS COMPANY_ID
FROM
#DSN2_ALIAS#.INVOICE I,
SETUP_CITY SC,
COMPANY C
WHERE
MONTH(INVOICE_DATE) >= 1
AND MONTH(INVOICE_DATE) < 12
AND C.COMPANY_ID=I.COMPANY_ID
AND SC.CITY_ID=C.CITY
AND PURCHASE_SALES=1
GROUP BY
DATEPART(MM,INVOICE_DATE),
SC.CITY_ID,
C.FULLNAME,
C.COMPANY_ID
</cfquery>
here is the definitions for lists:
<cfloop list="#month_list#" index="month_index">
<cfloop list="#cities_list#" index="city_index">
<cfoutput query="GET_SALES_TOTAL">
<cfif city_id eq city_index and AY eq month_index>
<cfloop list="#type_index#" index="tt_index">
<cfset 'alan_#tt_index#_#city_index#_#month_index#' = evaluate(tt_index)>
<cfset 'alan2_#city_index#_#tt_index#_#month_index#' = evaluate(tt_index)>
</cfloop>
<cfloop list="#c_index#" index="cc_index">
<cfif cc_index eq company_id>
<cfset 'company_#cc_index#_#city_index#_#month_index#' = evaluate(cc_index)>
</cfif>
</cfloop>
</cfif>
</cfoutput>
</cfloop>
</cfloop>
and here's the table:
<cfloop list="#month_list#" index="m_index">
<tr class="color-row" height="20">
<td width="150" nowrap><b><cfoutput>#left(listgetat(month_list_name,listfind(month_list,m_index)),20)#</cfoutput></b></td>
<cfloop list="#cities_list#" index="ddd_other">
<cfloop list="#type_index#" index="ii_index">
<td align="center">
<cfif isdefined('alan_#ii_index#_#ddd_other#_#m_index#') and len(evaluate('alan_#ii_index#_#ddd_other#_#m_index#'))>
<cfset all_toplam=evaluate('alan_#ii_index#_#ddd_other#_#m_index#')+all_toplam>
<cfset 'total_#ii_index#_#m_index#'=evaluate('total_#ii_index#_#m_index#') + #evaluate('alan_#ii_index#_#ddd_other#_#m_index#')#>
<cfset 'total2_#ddd_other#'=evaluate('total2_#ddd_other#') + #evaluate('alan2_#ddd_other#_#ii_index#_#m_index#')#>
<cfif listfindnocase('NETTOTAL',ii_index)>
<cfif isdefined('attributes.money') and attributes.money is 2>
<cfoutput>#TLFormat((evaluate('alan_#ii_index#_#ddd_other#_#m_index#')/get_money.rate2),2)#</cfoutput>
<cfelse>
<cfoutput>#TLFormat(evaluate('alan_#ii_index#_#ddd_other#_#m_index#'),2)#</cfoutput>
</cfif>
<cfelse>
<cfif isdefined('attributes.money') and attributes.money is 2>
<cfoutput>#TLFormat((evaluate('alan_#ii_index#_#ddd_other#_#m_index#')/get_money.rate2),2)#</cfoutput>
<cfelse>
<cfoutput>#TLFormat(evaluate('alan_#ii_index#_#ddd_other#_#m_index#'),2)#</cfoutput>
</cfif>
</cfif>
<cfelse>
0
</cfif>
<cfloop list="#c_index#" index="co_index">
<cfif listfindnocase('COMPANY_ID',co_index)>
<cfoutput>#evaluate('company_#co_index#_#ddd_other#_#m_index#')#</cfoutput>
</cfif>
</cfloop>
</td>
</cfloop>
</cfloop>
<cfloop list="#type_index#" index="kk_ind">
<td align="center" class="txtbold">
<cfif isdefined('attributes.money') and attributes.money is 2>
<cfoutput>#TLFormat((evaluate('total_#kk_ind#_#m_index#')/get_money.rate2),2)#</cfoutput>
<cfelse>
<cfoutput>#TLFormat(evaluate('total_#kk_ind#_#m_index#'),2)#</cfoutput>
</cfif>
</td>
</cfloop>
</tr>
</cfloop>
it says: Variable company_COMPANY_ID_1_1 is undefined. where is my mistake? i cant evaluate the LIST of company_idies in the same way i evaluated the NETTOTAL, since net total is not the list, but only one value... And thank you all for the help and attention! ;)
回答1:
There are a lot of things you can improve in this code.
Incrementing the number of cities inside a loop is unnecessary. You can get the count directly from SQL (select count(*) from setup_city
) or from CF after building your list (listlen(cities_list
).
For that matter, it's unnecessary to loop through the list manually when you can simply use ValueList to have CF do the work for you:
cities_list = ValueList( get_city.city_id );
cities_list_name = ValueList( get_city.city_name );
There's no reason to build a list of months if all you're ever going to do is loop from 1 to 12. Use the 1-to-12 loop instead.
type_index
doesn't need to be a list if you only have one item. Use the variable instead. Replace it with a list only when you actually need a list; this will also remove the need to use evaluate
, which is making your code hard to read and difficult for people to follow. Same thing for cc_index
.
Because scopes can be accessed as if they were structs, it's generally better (and can be significantly faster) to use structkeyexists( attributes, "money" )
rather than isdefined( "attributes.money" )
. Specifying the scope for isdefined
does help, of course ... isdefined( "money" )
is not only slow, but could return a completely different variable if you're not careful.
Speaking of structs, I would definitely recommend that you use them rather than concatenated variable names. It's extremely difficult to parse what you have written in order to understand what you are trying to do: using structs would make it easier to follow.
Finally, it looks to me like you're doing a ton of work in ColdFusion to do something that your database could do for you much more easily. If you need grand totals for companies by city, why not just do this?
<cfquery name="GET_SALES_GRAND_TOTAL" datasource="#dsn#">
SELECT
SUM(NETTOTAL) NETTOTAL,
SC.CITY_ID,
C.FULLNAME,
C.COMPANY_ID AS COMPANY_ID
FROM
#DSN2_ALIAS#.INVOICE I,
SETUP_CITY SC,
COMPANY C
WHERE
MONTH(INVOICE_DATE) >= 1
AND MONTH(INVOICE_DATE) < 12
AND C.COMPANY_ID=I.COMPANY_ID
AND SC.CITY_ID=C.CITY
AND PURCHASE_SALES=1
GROUP BY
SC.CITY_ID,
C.FULLNAME,
C.COMPANY_ID
</cfquery>
Is there a need to check that the month is between 1 and 12? If INVOICE_DATE exists, then it has to have a month between 1 and 12. I would either remove those lines from the query entirely or replace them with INVOICE_DATE IS NOT NULL
.
You should then be able to get your table of results with something that looks roughly like this:
<cfoutput query="GET_SALES_TOTAL" group="AY">
<!--- months first --->
<tr>
<!--- month-specific stuff goes here --->
<td>month_header</td>
<cfoutput group="city_id">
<!--- city-specific stuff --->
<td><!--- format NETTOTAL however you want here ---></td>
</cfoutput>
</tr>
</cfoutput>
<tr>
<td>grand_total_header</td>
<cfoutput query="GET_SALES_GRAND_TOTAL" group="city_id">
<td><!--- format NETTOTAL here ---></td>
</cfoutput>
</tr>
Hopefully this is of some help to you. I would strongly encourage you to read up on arrays and structs; someone using evaluate
is typically doing it the hard way when there is a much easier way of managing things, and there are plenty of examples both on SO and elsewhere of CF code that you should be able to learn from.
来源:https://stackoverflow.com/questions/6583307/evaluate-list-of-coldfusion-variables