使用ColdFusion(2016)循环遍历电子表格数据并将输出分组

时间:2018-02-19 00:54:00

标签: coldfusion cfloop coldfusion-2016

我提前就问题的长度道歉!我正在尝试为我们的活动自动构建论文时间表。纸张和作者数据在电子表格中提供(我的可怜的同事目前用它来手动剪切并粘贴到Word文档中)。此电子表格包含在一致命名的列中构建计划所需的所有信息,但它可以按任何顺序排列。有点像这样(但真正的纸质标题不会被方便地编号):

Jack Doe - Co-Author - Penn State University - Aerodynamics - Aerodynamics Paper I    
John Doe - Co-Author - Penn State University - Acoustics - Acoustics Paper I
John Smith - Co-Author - University of VA - Acoustics - Acoustics Paper I
Jane Doe - Main Author - Penn State University - Acoustics - Acoustics Paper I
Bob Smith - Main Author - GA Tech - Acoustics - Acoustics Paper II
Jack Smith - Main Author - University of MD - Acoustics - Acoustics Paper III
Jill Smith - Co-Author - University of MD - Acoustics - Acoustics Paper III
Bob Doe - Main Author - Penn State University - Aerodynamics - Aerodynamics Paper I

我的目标是对电子表格数据进行变换,使得论文按会话分组和排序(即声学,空气动力学),然后按纸质标题(即声学论文I,声学论文II),然后由每所大学的作者进行。问题在于"主要作者"对于任何给定的论文,必须首先列出来自同一所学校的共同作者(如果有的话),然后是其他大学的共同作者。其他共同作者可以按任何顺序排列,但也必须按大学分组。

所以采用原始的例子,它应该是这样的:

ACOUSTICS
Acoustics Paper I
Jane Doe, John Doe, Penn State University; John Smith, University of VA

Acoustics Paper II
Bob Smith, GA Tech

Acoustics Paper III
Jack Smith, Jill Smith, University of MD

AERODYNAMICS
Aerodynamics Paper I
Bob Doe, Jack Doe, Penn State University

我快到了,但我只能把它送到

ACOUSTICS
Acoustics Paper I
Jane Doe, Penn State University; John Doe, Penn State University; John Smith, University of VA;

Acoustics Paper II
Bob Smith, GA Tech;

Acoustics Paper III
Jack Smith, University of MD; Jill Smith, University of MD;

AERODYNAMICS
Aerodynamics Paper I
Bob Doe, Penn State University; Jack Doe, Penn State University;

我们正在使用ACF 2016.我正在做什么(我的代码在下面)是使用cfspreadsheet将电子表格读入查询对象。然后我按会话对输出进行分组,然后使用嵌套的cfoutputs对标题进行分组。

然后,因为我无法想出任何其他方法来识别每篇论文的主要作者并将它们放在第一位,我会为该论文循环所有作者并添加一个标志来识别它们,并使用arraySort对其进行排序。请注意,我不能简单地按作者类型DESC排序,因为还有另一种类型,"呈现作者,"我为了简洁省略了(ha)。有时主要作者也可以作为呈现作者,因此该类型将是主要作者呈现作者。"

无论如何,我然后循环遍历排序的数组。

以下是我到目前为止所尝试的内容。我坚持让大学只为每个作者名单展示一次。我已尝试在authorArray循环中添加另一个循环,但我不知道要索引或循环的内容,因此它最终会在每个作者姓名后输出大学名称。我已经尝试过使用多维数组,甚至使用查询查询来尝试构建一个漂亮的有序数据结构。但我显然做错了,因为我总是因为他们的大学将作者分组而感到难过。

我肯定会感激任何提示或提示!请注意,我无法更改最初使用此电子表格的要求。但是,一旦我得到它,我可以用我需要的信息做任何事情来获得所需的输出。所以我完全愿意做出任何改变或重新思考我的整个方法。我的代码是我得到的最接近的代码。

非常感谢大家!以下是我目前使用的内容:

<cfoutput query="queryPapers" group="PrimarySession">
    #PrimarySession#
    <cfoutput group="Title">
       <p>#Title#</p>
        <cfset authorArray = arrayNew(1)>
        <cfoutput>
            <cfset authorStruct = structNew()>
            <cfset authorStruct.firstName = AuthorFirstName>
            <cfset authorStruct.lastName = AuthorLastName>
            <cfset authorStruct.institution = AuthorInstitution>
            <cfset authorStruct.authorType = AuthorType>

            <cfif findNoCase("Main", AuthorType)>
                <cfset authorStruct.authorMain = "A">
            <cfelse>
                <cfset authorStruct.authorMain = "B">
            </cfif>

            <cfset arrayAppend(authorArray, authorStruct)>

            <cfscript>
                arraySort(
                    authorArray,
                    function (e1, e2) {
                        return compare(e1.authorMain, e2.authorMain);
                    }
                );
            </cfscript>
        </cfoutput>

        <cfloop index="i" from="1" to="#arrayLen(authorArray)#">
            #authorArray[i].firstName# #authorArray[i].lastName#,
            #authorArray[i].institution#;&nbsp;
        </cfloop>
    </cfoutput>
</cfoutput>

以上是上述代码的实际输出:

Dynamic Stall Investigations
  Sergey Smith,* University of Maryland;  Tobias Lersdorf, German University;  Pascal Marceau, University of Maryland;  

我正试着去

Dynamic Stall Investigations
  Sergey Smith,* Pascal Marceau, University of Maryland;  Tobias Lersdorf, German University

非常感谢阅读!

1 个答案:

答案 0 :(得分:2)

您使用代码进入了正确的轨道,但我认为您过度复杂了一些。您可以使用下面的代码段简化嵌套<cfoutput>处理。

<!--- Nested output loop for displaying required result --->
<cfoutput query="queryPapers" group="PrimarySession">
    <strong>#Ucase(PrimarySession)#</strong><br />
    <cfoutput group="Title">
        <i>#Title#</i><br />
        <cfoutput group="AuthorInstitution">
            <cfoutput>
                #AuthorFirstName# #AuthorLastName#,
            </cfoutput>
            #AuthorInstitution#; <!--- display institution once per group --->
        </cfoutput>
        <br /><br /> <!--- double-space after each title group --->
    </cfoutput>
</cfoutput>
  1. 只有一次显示大学的问题可以通过添加另一级别的组嵌套并将其显示在额外嵌套组的页脚中来实现。

  2. 确保主要作者始终是第一位的问题应该在预处理中处理。为此,请使用现有的if / else逻辑(&#34; A&#34;对于主要作者,&#34; B&#34;否则)并将其作为额外列添加到查询中。通过这种方式,您可以在输出循环之前在order by子句中使用它。

  3. <强>更新

    所以我在发布第一次修订后意识到存在一个小的逻辑缺陷。它没有浮出水面的原因是因为在使用上面的样本数据时,主要作者方便地总是属于大学,该大学按字母顺序排在&#34;标题&#34;组。在看到额外的示例输出后我意识到这一点,我将这些行添加到我的代码示例中,它也错误地显示如下。

    Dynamic Stall Investigations
    Sergey Smith, University of Maryland; Tobias Lersdorf, German University;  Pascal Marceau, University of Maryland;
    

    解决方案是使用现有的authorMain列(主要作者为A,否则为B),并为属于同一所大学的非主要作者添加另一个值A2。主要作者。棘手的部分是你必须检查另一行中的值以确定何时设置A2。我能想到的最好的解决方案是在添加最初填充的authorMain列后立即添加两个代码块。

    <!--- Sort query so "Main Author" is first within PrimarySession and Title --->
    <cfquery name="queryPapers" dbtype="query">
        select * from queryPapers
        order by
            PrimarySession, 
            Title, 
            AuthorMain
    </cfquery>
    
    <!--- Loop through above and update NON "Main-Author" rows "A2" if they have same University as "A" rows  --->
    <cfset MainInstitution = "">
    <cfloop query="queryPapers">
        <cfif queryPapers.authorMain eq "A">
            <cfset MainInstitution = queryPapers.AuthorInstitution>
        <cfelse>
            <cfif MainInstitution eq queryPapers.AuthorInstitution>
                 <cfset QuerySetCell(queryPapers, "authorMain", "A2", queryPapers.currentRow)>
            </cfif>
        </cfif>
    </cfloop>
    

    首先按PrimarySession,Title和AuthorMain进行排序,然后循环遍历记录集并使用A2更新行,如果非主要作者与主作者在同一所大学中,则使用{{1}跟踪变量。此解决方案生成正确的结果,同时允许所有其他代码保持不变。

    您可以看到我的代码的第一个revision和第二个revision之间的差异,它模拟了OP的情景。