• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 294
  • Last Modified:

How would I write this loop?

Attached is a screen shot of a page I'm working on.

I would direct your attention to the right screen and if you enlarge it some, you'll see at the very top, some data that looks like this:

Bellingham
(add) Approver
          Group Vice President

The code that I'm using to generate these results represents a convention that I need to stay consistent with, just because I'm a guest in this equation and I want to be courteous in that regard.

That said, I'm stuck.

Here's my code:

$cur_approverentityid=0;
			for($i=1; $i<=$modelentitylist["count"]; $i++)
			{
				if($cur_approverentityid != $modelentitylist[$i]["entityid"])
				{
				echo "
				<tr><td width='40' class='textsmall'>&nbsp;</td><td colspan='3' class='greeting_section' valign='middle'>".$modelentitylist[$i]["EntityName"]."</td></tr>";
					if(trim($modelentitylist[$i]["EntityName"])<>"")
					{
						for($k=1; $k<=$workqueuetypelist["count"]; $k++)
						{
						echo "
						<tr><td width='40' class='textsmall' bgcolor='#cccccc' align='center'><a href='workqueueentity_addedit.php?ID=0&entityid=".$modelentitylist[$i]["entityid"]."&workqueuetypeid=".$workqueuetypelist[$k]["workqueuetypeid"]."'>(add)</a></td><td colspan='3' class='greeting_section' valign='middle' bgcolor='#cccccc'>".$workqueuetypelist[$k]["shortname"]."</td></tr>";
							//here is where you're listing your people based on their 
							if($modelentitylist[$i]["workqueuetypeid"]==$workqueuetypelist[$k]["workqueuetypeid"])
							{
							echo "<tr><td width='40' class='textsmall'>&nbsp;</td><td><span class='text'>".$modelentitylist[$i]["defaultname"]."</span></td></tr>";
							}
						}
					}
				}
				//here's the beginning of every one of your workqueue types
		$cur_approverentityid = $modelentitylist[$i]["entityid"];
		}

Open in new window


My quandary is that for Bellingham, I've got two approvers and the way my code is set up right now, I'm only going to see one because of the way I've set things up so if there is more than one row that corresponds to "Bellingham," you won't see it and the result is a clever way of being able to next some "for" loops within one another and avoid unwanted redundancy.

But in this case, I had to assert a dynamic that I've yet to be able to figure out. For each hospital, you have a possibility of five different Role Types (Approver, Financing, Fixed Assets, Purchasing, Validator). I'm grabbing those Roles from a separate table and nesting them in the middle of each hospital facility as they're being listed.

Everything is wonderful right up to the point where I've got a situation like in Bellingham where I've got two "Approvers." Because of that if statement at the very top that prohibits a facility from being listed twice, I can't access that second Role Type.

I know what you're thinking: "Why not just list everything as it is in the table and not worry about documenting every Role Type if it's not in the table?" Because the scope of this project necessitates the ability to "add" a Role Type, hence the position I'm in.

So...

How do I loop through all of the possibilities at each juncture? I tried writing another "for" loop and the result was this:

	if($modelentitylist[$i]["workqueuetypeid"]==$workqueuetypelist[$k]["workqueuetypeid"])
							{
							$workqueueapproverlist = cer_workqueueentityapprover($modelentitylist[$i]["entityid"], $modelentitylist[$i]["workqueuetypeid"]);
								for($j=1; $j<=$workqueueapproverlist["count"]; $j++)
								{
								echo "<tr><td width='40' class='textsmall'>&nbsp;</td><td><span class='text'>".$workqueueapproverlist[$j]["defaultname"]."</span></td></tr>";
								}
							}

Open in new window


I was stoked, but then I got an error that I've never seen before that said "No tuples available at this result index in E:\inetpub\wwwroot\mytenbi\app\cer\cer_functions.php on line 812" and I"ve got that code for you right here:

function cer_workqueueentityapprover($EntityID, $WorkqueueTypeID) {
        global $edb,$_SESSION;
        
      $result_data = odbc_exec($edb, $sql_data);
	
	$count=0;
	while (odbc_fetch_row($result_data))
		{
		$count++;
		$data[$count]["workqueuetypeid"]=odbc_result($result_data,"workqueuetypeid");
		$data[$count]["shortname"]= htmlspecialchars(odbc_result($result_data, "shortname"), ENT_QUOTES);
		$data[$count]["workqueueroleid"]= odbc_result($result_data, "workqueueroleid");
		$data[$count]["defaultname"]= htmlspecialchars(odbc_result($result_data, "defaultname"), ENT_QUOTES);
		$data[$count]["overridename"]= htmlspecialchars(odbc_result($result_data, "overridename"), ENT_QUOTES);
		$data[$count]["sortorder"]= odbc_result($result_data, "sortorder");
		$data[$count]["entityid"]= odbc_result($result_data, "entityid");
		}
	$data["count"]=$count; 
	return $data;
	}

Open in new window


So, there's probably more than one "right" way to do this, but I need to stay consistent with my boss' approach. That said, how can I make this puppy sing?
0
brucegust
Asked:
brucegust
  • 2
1 Solution
 
Ray PaseurCommented:
I'm not sure I know what to tell you - it looks like you're painted into a corner with a brittle data design that broke when "real world" factors intruded.  Here are some philosophical notes that might help you get it on the right track.

There are three numbers of data elements that matter: Zero, One, and Infinity.  Your code would be designed to work with one of those numbers.  If Zero is expected, you would test for the presence of the data element and if found you would throw an exception.  If One is expected you would test for Zero and more than One and if either condition is found you would throw an exception.  If more than one is permitted, the general design is to program for Infinity by using while() and foreach() iterators.  Of course in practice you do not get an infinite number of elements and sanity checks are used to avoid things like overly long queues, but you get the idea.  

A related concept is data base normalization, where data kept in any given row can be normalized against other data with the zero, one, or infinity number.  If there can only be one of a given child element, you can put it into the row with the master element and your code will work well.  But when there can be more than one child for a given master element, a junction table or a JOIN query is necessary.  A one-to-many relationship can exists (and so can a many-to-many relationship).

I think to try to help we would need to see your CREATE TABLE statements and some test data.  Also, didn't we talk earlier about not putting $_SESSION into a global statement?  That problem seems to be back again.
0
 
brucegustPHP DeveloperAuthor Commented:
Hey, Ray!

I'm not ignoring your "not putting $_SESSION into a global statement," but I'm not comfortable "correcting" anything about my boss' convention, yet. Perhaps once I'm a little more tenured, I'll make said recommendation and we'll go from there.

I was able to figure out what to do. I had to "cheat" to make it happen, but it works. Bottom line: I nested my "for" loop BEFORE I tried to list what the results of my stored procedure was. Then I just did a little "if" statement to make sure that I wasn't repeating something that had already been listed. And...BAM! I'm going home!

Thanks for your time and feedback, Ray. As always, it's admired and appreciated.

$cur_approverentityid=0;
		$cur_workqueueentityid=0;
			for($i=1; $i<=$modelentitylist["count"]; $i++)
			{
				if($cur_approverentityid != $modelentitylist[$i]["entityid"])
				{
				echo "
				<tr><td width='40' class='textsmall'>&nbsp;</td><td colspan='3' class='greeting_section' valign='middle'>".$modelentitylist[$i]["EntityName"]."</td></tr>";
					for($k=1; $k<=$workqueuetypelist["count"]; $k++)
					{
						if($modelentitylist[$i]["workqueuetypeid"]<>$workqueuetypelist[$k]["workqueuetypeid"])
						{
						echo "
						<tr><td width='40' class='textsmall' bgcolor='#cccccc' align='center'><a href='workqueueentity_addedit.php?ID=0&entityid=".$modelentitylist[$i]["entityid"]."&workqueuetypeid=".$workqueuetypelist[$k]["workqueuetypeid"]."'>(add)</a></td><td colspan='3' class='text' valign='middle' bgcolor='#cccccc'>".$workqueuetypelist[$k]["shortname"]."</td></tr>";
						}
					}
					if($workqueueentityid != $modelentitylist[$i]["workqueueentityid"])
					{
					echo "<tr><td width='40' class='textsmall' bgcolor='#cccccc' align='center'><a href='workqueueentity_addedit.php?ID=0&entityid=".$modelentitylist[$i]["entityid"]."'>(add)</a></td><td colspan='3' bgcolor='#cccccc' class='text'>".$modelentitylist[$i]["WorkqueueTypeShortname"]."</td></tr>";
					}
				}
				echo"
				<tr><td width='40' class='textsmall'>&nbsp;</td><td colspan='3' class='text'>".$modelentitylist[$i]["defaultname"].' | '.$modelentitylist[$i]["entityid"]."</span></td></tr>";
					
				
				//here's the beginning of every one of your workqueue types
			$workqueueentityid = $modelentitylist[$i]["workqueueentityid"];
			$cur_approverentityid = $modelentitylist[$i]["entityid"];
				
			}

Open in new window

0
 
Ray PaseurCommented:
Yeah, that feels a bit like a hack, but if it gets the job done in the context, it's perfectly OK.  You might want to add some comments to explain it so that in the future when you or someone else reads the code and says, WTF the comments will make it clear.  I always believe in commenting the "why" and leaving the code to tell the "what" part of the story.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Cloud Class® Course: Python 3 Fundamentals

This course will teach participants about installing and configuring Python, syntax, importing, statements, types, strings, booleans, files, lists, tuples, comprehensions, functions, and classes.

  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now