Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
178 views
in Technique[技术] by (71.8m points)

Evaluate List of ColdFusion Variables

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! ;)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...