使用while循环生成报告

时间:2013-05-05 05:42:49

标签: php

我有一张表,其中包含各种条目,例如开始日期(合同),一些随机文件以及月结单和收据,如下所示:

DOCUMENT TYPES
ID TYPE        CHECK?     MONTHLY?
1  Contract    Yes        No
2  Documents   No         No
3  Policy      Yes        No
4  Order       No         No
5  Invoice     Yes        Yes
6  Receipt     Yes        Yes

文献

ID TYPE DATE
1  1    01/01/2013
2  2    01/01/2013
3  3    01/01/2013
4  5    01/02/2013
5  6    01/02/2013
6  4    14/02/2013
7  5    01/03/2013
8  6    01/03/2013


TODAY 05/05/2013

我的目标是生成输出,如下所示。 显示所有现有文件,CHECK在哪里?是的,并且每月显示丢失的文件?是的。

01  Contract    01/01/2013 OK
02  Documents   01/01/2013 OK
03  Policy          01/01/2013 OK
04  Invoice         01/02/2013 OK
05  Receipt         01/02/2013 OK
06  Invoice         01/03/2013 OK
07  Receipt         01/03/2013 OK
08  Invoice         01/04/2013 Missing
09  Receipt         01/04/2013 Missing
10  Invoice         01/05/2013 Missing
11  Receipt         01/05/2013 Missing

我已经写了一些代码,但我不明白如何包含每月循环来显示发票和收据。

QUERY

// Get type
$query = "SELECT * FROM doc_type
          WHERE check='1'";
$result = mysql_query($query) or die(mysql_error());
$num = mysql_numrows($result);  

// Get docs
$check = array();
$query2 = mysql_query("SELECT document_type_id FROM documents");
while ($row = mysql_fetch_assoc($query2)) {
$check[] = $row['document_type_id'];

WHILE

<tbody>
<?php
    $i=0;
        while ($i < $num) {
        $document_type_id = mysql_result($result,$i,"document_type_id");
        $document_type = mysql_result($result,$i,"document_type");
    ?>
    <tr class="grade">

    <td><?php echo $document_type_id; ?></td>
    <td><?php echo $document_type; ?></td>
    <td>
    <?php 
        if (in_array($document_type_id, $check)) { 
        echo "<p style='color:green'>Ok</p>";
        } else {
        echo "<p style='color:red'>Miss</p>";   
        }
     ?>
     </td>
     </tr>
     <?php
         $i++;
         }
      ?>                    
</tbody>

1 个答案:

答案 0 :(得分:1)

首先,我必须指出我对示例数据感到有些困惑,因为它看起来像是从第一个表的数据库加载数据,但是示例意味着有一个文档列表正在为每个工作或项目保存在其他地方。

如果是我,我会创建一个代表你的决赛桌的对象或数组。然后,您可以根据可用数据填充该对象。鉴于您似乎已经使用的数据结构,我将假设您不希望使用面向对象的编程方法。

首先,创建一个数组或对象,用于存储与文档类型和月度设置匹配的原始表信息。选择数据格式后,您可以从数据库中为每组不同的设置加载数据格式。我将使用您在示例中显示的设置。

就个人而言,我会使用文档类型id作为索引键,并使用布尔值来表示Yes(true)和No(false),如下所示:

$doc_requirements = array(
    1 => array( "name" => "Contract", "check" => true, "monthly" =>  false ),
    2 => array( "name" => "Documents", "check" => false, "monthly" => false ),
    3 => array( "name" => "Policy", "check"=>true, "monthly"=>false ),
    4 => array( "name" => "Order", "check"=>false, "monthly"=>false ),
    5 => array( "name" => "Invoice", "check"=>true, "monthly"=>false ),
    6 => array( "name" => "Receipt", "check"=>true, "monthly"=>false )
);

使用您的数据库根据需要存储这些表,并在查看文档列表之前加载它们。

接下来,我将创建一个表示输出表的数组。按日期对其进行索引,以便确定是否缺少文档。您的数据意味着在每个日期,我们可以拥有多个文档,但不能超过一个相同类型的文档,因此您可以使用以下内容:

/* pseudo_code */ $temp_table = array( 
      [date] => array( 
           [doc_type_name] => array(
                /* I assume that the document id is actually just the line number 
                  on the table, so I will leave the id out of this, but if it is 
                  not just the line on the table, add this field to the array: 
                       "id" => [id], */ 
                "status" => [status] )
            ),
           [doc_type_name] => array(
                "status" => [status] )
            ),
            ...
       ),
      [date2] => array(  ... ),
       ....
  );

使用您从文档数组中了解的文档加载此数组:

(注意:您正在使用当前已弃用的mysql函数,因此您应该考虑使用msyqli函数)

$sql = #### /* SQL query string for your list of documents that are not missing */
$result = mysql_query($sql) or die(mysql_error());
if($result){
    while( $document = mysql_fetch_assoc( $result ) ){
         $date = $document[ "date" ];
         $doc_type_id = $document[ "type_id" ];
         $doc_type_name = $doc_requirements[ $doc_type_id ]["name"];
         $temp_table[ $date ][ $doc_type_name ]["status"]= "OK" 
         /* we have the document, therefore, we know it is okay, 
            we can set that value immediately */
    }
}
$start_date=#### /* set start date of contract */
$end_date=##### /*set end date of contract */
foreach( $doc_requirements as $requirement ){
    if( $requirement["monthly"] == true ){
        for( $cur_date = $start_date; $cur_date <= $end_date; $cur_date=#### ){ 
                 /*increment the date by whatever function you choose, 
                   I recommend using a DateTime object 
                   for your dates and incrementing by using the add() method */
            $current_doc_name = $requirement[ "name"];
            if( !isset( $temp_table[$cur_date][ $current_doc_name ] ) ){
                /* if the array value is not set, 
                   then a document of the type_name 
                   and current date specified does not exist,
                   because the requirement for "monthly" == true, 
                    we know that we should have it, so we will 
                   set the status to "Missing" */
                $temp_table[$cur_date][$current_doc_name]["status"] = "Missing";
            }
        }
    }
}

现在我们有一个按日期组织的数组,包含我们在数据库中记录的每个文档的一个文档记录(但每个日期的每种类型不超过一个... 如果您需要更改这样,只需更改数组的数据结构以满足您的需求,或使用面向对象的方法来帮助更自然地绘制您的想法)。对于Monthly = true( YES )的任何项目,我们为其创建了一个“Missing”存根,表明在那里预期但未找到。有了这个数据数组,我们就可以遍历它并产生输出。

我上面已经注意到你的文档ID似乎只是输出表上的行号,所以我将在这里用相同的方式表示它:

$doc_id = 1;
foreach($temp_table as $cur_date){
    foreach($cur_date as $doc_name){
        $doc_id_string = your_func_format_id( $doc_id ); 
         /* use whatever function you like to make your doc_id two digits. 
            Perhaps printf() would be useful */
        $color_code = "style='color:green'";
        if( $doc_name["status"]=="Missing" ) $color_code = "style='color:red'";
        echo "<tr class='grade'><td>$doc_id_string</td><td>$doc_name</td><td>$cur_date</td><td><p $color_code>{$doc_name["status"]}</p></td>";
    }
}

我了解到使用正确的数据结构会使一切变得更简单。我试图使用反映您的示例代码的数据结构。我强烈建议使用面向对象编程(OOP)技术来实现您的设计,因为OOP强制每个程序员在考虑编程代码之前考虑数据的形状,并且它解决了许多问题。