Download presentation
Presentation is loading. Please wait.
Published byΆνθεια Γιάγκος Modified over 5 years ago
1
Arrays, Structures, Multidimensional Arrays, Arrays of Structures
Or what I like to call them, "Complex Containers" CFUNITED – The premier ColdFusion conference
2
(the wife inserted that one!)
About Me I own KomputerMan.com, a 1 employee Cold Fusion application development consulting company. Developing CF applications since 1998 and have been consulting since 1999. I am not one of those people who has the time to delve into how CF does its magic. I am much more concerned with how I can use CF to make my own magic! Oh yeah… and I like to talk. (the wife inserted that one!) June 28th – July 1st 2006
3
What we are going to discuss
Overview of an Array and a Structure. Create, write to, and retrieve data from a 1 dimensional array, a 2 dimensional array, and a structure. The challenge and the database schema created to meet that challenge. Create and populate a 2 dimensional array that contains a 2 dimensional array. Add a structure to the multi dimensional array. What I call a Complex Container. June 28th – July 1st 2006
4
What we are going to discuss
Loop through the complex container. Pass the data to another process. Show you where to get a sample code to create your own complex container. Questions at the end. Reminder: There are many ways to do accomplish the same work using CF. I am not here to tell you the methods we are about to discuss is the only way or even the best way to do something, this is just one way of doing things. But I thought it was pretty cool! June 28th – July 1st 2006
5
The 1 Dimensional Array An Array is a virtual container used to store data. Think of a 1 Dimensional Array as a named list referenced by sequential integers. June 28th – July 1st 2006
6
The 1 Dimensional Array First you define the Array with a unique name.
<CFSET Aerosmith = ArrayNew(1)> Use CFSET to populate the array as shown below. <CFSET Aerosmith[1] = 'Tom'> <CFSET Aerosmith[2] = 'Joe'> <CFSET Aerosmith[3] = 'Brad'> <CFSET Aerosmith[4] = 'Joey'> <CFSET Aerosmith[5] = 'Steven'> Notice the sequential integer referencing of ArrayName[RowSequence]. June 28th – July 1st 2006
7
The 1 Dimensional Array I prefer to loop through an Array when viewing or working with the data stored in the container. <CFLOOP FROM="1" TO="#ArrayLen(Aerosmith)#" INDEX="xx"> <CFOUTPUT> Aerosmith[#xx#] = #Aerosmith[xx]# <BR> </CFOUTPUT> </CFLOOP> Output looks like this: Aerosmith[1] = Tom Aerosmith[2] = Joe Aerosmith[3] = Brad Aerosmith[4] = Joey Aerosmith[5] = Steven June 28th – July 1st 2006
8
The 2 Dimensional Array Think of a 2 dimensional array as a spreadsheet with the rows and columns referenced by sequential integers. Rows get referenced first, then columns. June 28th – July 1st 2006
9
The 2 Dimensional Array First you define the Array with a unique name.
<CFSET Aerosmith = ArrayNew(2)> Then populate the Array as shown below. <CFSET Aerosmith[1][1] = 'Tom'> <CFSET Aerosmith[1][2] = 'Hamilton'> <CFSET Aerosmith[2][1] = 'Joe'> <CFSET Aerosmith[2][2] = 'Perry'> <CFSET Aerosmith[3][1] = 'Brad'> <CFSET Aerosmith[3][2] = 'Whitford'> <CFSET Aerosmith[4][1] = 'Joey'> <CFSET Aerosmith[4][2] = 'Kramer'> <CFSET Aerosmith[5][1] = 'Steven'> <CFSET Aerosmith[5][2] = 'Tyler'> Notice the referencing of ArrayName[Row][Column]. June 28th – July 1st 2006
10
The 2 Dimensional Array Loop through the Array.
<CFLOOP FROM="1" TO="#ArrayLen(Aerosmith)#" INDEX="xx"> <CFOUTPUT> Aerosmith[#xx#] = #Aerosmith[xx][1]# - #Aerosmith[xx][2]#<BR> </CFOUTPUT> </CFLOOP> Output looks like this: Aerosmith[1] = Tom - Hamilton Aerosmith[2] = Joe - Perry Aerosmith[3] = Brad - Whitford Aerosmith[4] = Joey - Kramer Aerosmith[5] = Steven - Tyler June 28th – July 1st 2006
11
2-D Array KDL Preferences
I prefer to know the number of "columns" stored in the Array. Formatting the output is easier if the number of columns are known. I don't care about the number of Rows in an Array because I use '#ArrayLen(ArrayName)#' and I like to Loop! Name the array something that is indicative of the data being stored inside of it. June 28th – July 1st 2006
12
The Structure Think of a structure as a 1 dimensional array that can be referenced by alphanumeric text. FirstName.['Tom'] Hamilton FirstName.['Joe'] Perry FirstName.['Brad'] Whitford FirstName.['Joey'] Kramer FirstName.['Steven'] Tyler June 28th – July 1st 2006
13
The Structure Think of a structure as a database table with two columns, 1 column is the primary key and the other column is the value column. Biggest difference between the structure and the 1 dimensional array is that arrays are referenced by sequential numbers and structures can be referenced by alphanumeric text or sequential numbers. Arrays are sorted, and structures are not. First in does not mean first out when looping through a structure. June 28th – July 1st 2006
14
How to Populate a Structure
First define the Structure with a unique name <CFSET Aero_Struct = StructNew()> Use CFSET to populate the structure <CFSET Aero_Struct ['Tom'] = 'Hamilton'> <CFSET Aero_Struct ['Joe'] = 'Perry'> <CFSET Aero_Struct ['Brad'] = 'Whitford'> <CFSET Aero_Struct ['Joey'] = 'Kramer'> <CFSET Aero_Struct ['Steven'] = 'Tyler'> Notice the referencing by alphanumeric characters, also referred to as a 'Key - Value' pair. 'Tom' would be the KEY and 'Hamilton' would be the value. June 28th – July 1st 2006
15
Contents of a Structure
I generally do not loop through a structure when viewing or working with the data stored in the structure, but you can like this <CFLOOP COLLECTION="#Aero_Struct#" ITEM="MyName"> <CFOUTPUT> #MyName# - #Aero_Struct[MyName]#<BR> </CFOUTPUT> </CFLOOP> Output MAY look like this (order is not guaranteed): Tom - Hamilton Brad - Whitford Joey - Kramer Steven - Tyler Joe - Perry June 28th – July 1st 2006
16
Structure KDL Preferences
I don't like to loop through a structure because the data in the structure is un-sorted. First in doesn't mean first out! Structures are great for lookup values. Name you structure something that is indicative of the data being stored inside of it. June 28th – July 1st 2006
17
That’s Enough of the Easy Stuff
Here is the challenge… I have reports that can be automatically generated daily, weekly, monthly, quarterly, or yearly. Each report has its own set of variables that are used to generate the report. (I.E. 'Agency_Name, Project_Manager, etc...') One or more users can receive the report when it gets generated. Each user has their own values that get passed into the report as variables. (I.E. for User 1 Agency_Name = 'Dept. of Admin', for User 2 Agency_Name = 'Health and Welfare') How do I put all of that into an Array like container??? June 28th – July 1st 2006
18
The Database Schema June 28th – July 1st 2006
19
About the Database The ReportNames table stores data about the report itself, such as… The ReportName is the logical path to the *.cfm template to be executed. IsActive tells me if this report is still active (Y/N). StartDate tells me when to start generating the report. RptFrequency tells me how often to generate the report. (daily, weekly, etc...) The fields pass along some information to the CFMAIL tag when the report gets mailed out to the user. June 28th – July 1st 2006
20
About the Database The ReportParams table stores data about the variables that the report will accept. The ParamName is the name of the parameter, I.E. 'Agency_Name'. ParamDefaultValue is the default value of the parameter in case a customized value does not get passed to the report (I.E. 'Dept. of Admin'). ParamDesc is just a description of the parameter so I can remember what was getting passed and why. RptNameCnt links the parameter to a specific report. June 28th – July 1st 2006
21
About the Database The ReportUsers table tells me which users will get which reports. One user can receive multiple reports and one report can be generated for multiple users. RptNameCnt is the link to a specific report. UserCnt is the link to a specific User. The ReportUserParams table tells me what the User value is for each parameter associated to the report. RptParamCnt is the link to a specific report parameter. RptUserCnt is the link to a specific User receiving a specific report. UserParamValue is the value of the parameter to be passed to the report for this user, I.E, 'Health and Welfare'. June 28th – July 1st 2006
22
Build the Array Get the data about the report itself
Run a similar query for week, month, and year This example only deals with daily reports <CFQUERY NAME="GetDaily" DATASOURCE="#Request.dsn#"> SELECT RptNameCnt, ReportName, Subject, Body, Sender FROM ReportNames WHERE RptFrequency = 'DAY' AND IsActive <> 0 AND StartDate <= #CreateODBCDate(Now())# </CFQUERY> June 28th – July 1st 2006
23
Build the Array Put the data into an Array called ReportArray
<CFSET ReportArray = ArrayNew(2)> <CFSET MyCnt = 1> <CFIF GetDaily.RecordCount NEQ 0> <CFOUTPUT QUERY="GetDaily"> <CFSET ReportArray[MyCnt][1] = GetDaily.RptNameCnt> <CFSET ReportArray[MyCnt][2] = GetDaily.ReportName> <CFSET ReportArray[MyCnt][3] = GetDaily. Body> <CFSET ReportArray[MyCnt][4] = GetDaily. Sender> <CFSET ReportArray[MyCnt][5] = GetDaily. Subject> <CFSET ReportArray[MyCnt][6] = ArrayNew(2)> <CFSET MyCnt = MyCnt + 1> </CFOUTPUT> </CFIF> June 28th – July 1st 2006
24
Build the Array Notice the line that creates a 2 dimensional array in the existing 2-D Array. <CFSET ReportArray[MyCnt][6] = ArrayNew(2)> The Variable MyCnt increments to keep track of each row in the array. <CFSET MyCnt = MyCnt + 1> The CFOUTPUT tag loops through the GetDaily record set. June 28th – July 1st 2006
25
Add Users to ReportArray
Now that we know what reports are going to be generated find the users to get the reports. Loop through the array and run a query based on the reports stored in the array. There are other ways to do this in SQL but for long term maintenance I thought this would be easier. June 28th – July 1st 2006
26
Add Users to ReportArray
Loop through the ReportArray and get the Users associated to the report. <CFLOOP FROM "1" TO "#ArrayLen(ReportArray)# INDEX="cc"> <CFSET MyRptNameCnt = ReportArray[cc][1]> <CFQUERY NAME="GetUsers" DATASOURCE="#Request.dsn#"> SELECT RptUserCnt, Addr FROM ReportUsers, Users WHERE RptNameCnt = #MyRptNameCnt# AND Users.UserCnt = ReportUsers.UserCnt </CFQUERY> June 28th – July 1st 2006
27
Add Users to ReportArray
The CFSET command is optional, I like it to self document what my WHERE clause contains. The query returns the Primary key from the ReportUsers and the address associated to the user. The PK value will be used to get the users report parameters June 28th – July 1st 2006
28
Add Users to ReportArray
If the query returned any records add it to the ReportArray. Remember we are still inside the 1st loop. <CFIF GetUsers.RecordCount GT 0> <CFSET NewCnt = 1> <CFLOOP QUERY="GetUsers"> <CFSET ReportArray[cc][6][NewCnt][1] = GetUsers.RptUserCnt> <CFSET ReportArray[cc][6][NewCnt][2] = StructNew()> <CFSET ReportArray[cc][6][NewCnt][3] = GetUsers. Addr> June 28th – July 1st 2006
29
Add Users to ReportArray
If a user exists add them to ReportArray. Set NewCnt to keep track of the row of the 2nd MD array inside of the 1st one. Loop through the GetUsers Query to add the data to ReportArray. Syntax: ReportArray[cc][6][NewCnt][1] = GetUsers.RptUserCnt June 28th – July 1st 2006
30
Add Users to ReportArray
Create a structure in the 2nd cell of the 2nd MD array. Syntax: ReportArray[cc][6][NewCnt][2] = StructNew() The structure is named ReportArray[cc][6][NewCnt][2] June 28th – July 1st 2006
31
Add User Parameters While looping through the GetUsers Query get the Users parameters associated to the report. <CFQUERY NAME="GetParams" DATASOURCE="#Request.dsn#"> SELECT ParamName, UserParamValue FROM ReportUserParams, ReportParams WHERE RptNameCnt = #MyRptNameCnt# AND ReportUserParams.RptParamCnt = ReportParams.RptParamCnt AND RptUserCnt = #GetUsers.RptUserCnt# </CFQUERY> June 28th – July 1st 2006
32
Add User Parameters The query returns any specific user parameters associated to the person getting the report. Remember we are still inside the 1st loop (the ReportArray loop). We are also looping through the GetUsers Query. June 28th – July 1st 2006
33
Add User Parameters If the query returns any records add them to the structure in ReportArray. <CFIF GetParams.RecordCount GT 0> <CFLOOP QUERY="GetParams"> <CFSET ReportArray[cc][6][NewCnt][2]["#GetParams.ParamName#"] = GetParams.UserParamValue> </CFLOOP> </CFIF> The structure is populated with the key value pair returned from the query. June 28th – July 1st 2006
34
Add User Parameters Now we have all our data we close the loops.
<CFSET NewCnt = NewCnt + 1> </CFLOOP> </CFIF> Increment the 2nd MD array counter. Close the GetUsers query loop. The CFIF is closed if there were any GetUser records. Close the ReportArray loop. June 28th – July 1st 2006
35
Data In the Complex Container
ReportArray[1][1] = PK value of the report to be ran ReportArray[1][2] = Actual name of report to be ran (Report.cfm) ReportArray[1][3] = Text to be included in the body ReportArray[1][4] = address of the person sending the report ReportArray[1][5] = subject ReportArray[1][6] = 2nd Multidimensional array ReportArray[1][6][1][1] = PK of the person getting THIS report ReportArray[1][6][1][2] = Structure containing Key value pair of parameters and parameter value ReportArray[1][6][1][3] = addr of the person getting the report June 28th – July 1st 2006
36
View The Complex Container
Loop through the Complex Container to view the data. <CFLOOP FROM="1" TO="#ArrayLen(ReportArray)#" INDEX="xx"> <CFSET ReportName = "/YourApp/Reports/" & ReportArray[xx][2]> <CFLOOP FROM="1" TO="#ArrayLen(ReportArray[xx][6])#" INDEX="yy"> <CFINCLUDE TEMPLATE="#ReportName#"> </CFLOOP> June 28th – July 1st 2006
37
View The Complex Container
1st loop returns the report name. The CFSET tag sets up the relative path to the report template that gets included. The 2nd loop calls the report one time for each user receiving the report. The report uses the data in the array too. June 28th – July 1st 2006
38
The Report The report initializes all parameters.
If any of them are customized for the user. <CFLOOP COLLECTION="#ReportArray[xx][6][yy][2]#" ITEM="Param"> <CFIF Param EQ "AgencyCnt"> <CFSET MyAgencyCnt = ReportArray[xx][6][yy][2][Param]> </CFIF> <CFIF Param EQ "DelProj"> <CFSET MyDelProj = ReportArray[xx][6][yy][2][Param]> <CFIF Param EQ "HoldAct"> <CFSET MyHoldAct = ReportArray[xx][6][yy][2][Param]> </CFLOOP> June 28th – July 1st 2006
Similar presentations
© 2025 SlidePlayer.com Inc.
All rights reserved.