다중 for문 오류

다중 for문 오류

QA

다중 for문 오류

본문


    for($i=0; $row=sql_fetch_array($result); $i++)
    {
        for ($j=1; $j<=$row['linkCount']; $j++) {
//////////////////////////////////////////////////////////////////////
       }
    }

출력하면 01 02 03 11 12 13 14 21 22 23 24 25 이런식으로 나와야 하는데

01 02 03 13 14 24 25 이렇게 출력이 되네요.

$j값이 루프후 1로 돌아와야 하는데 그 전 출력된 값에 영향을 받는거 같은데요.

어떤 부분이 잘못되었는지 알려주실수 있을까요?

이 질문에 댓글 쓰기 :

답변 5

소스를 다 봐야 알 수 있지 않을까요?


include_once('./_common.php');

$csv = 'xls';

// MS엑셀 XLS 데이터로 다운로드 받음
if ($csv == 'xls')
{

	$wridStr = implode(',',$_POST['chk_wr_id']);

    $sql = " SELECT * FROM g5_write_{$bo_table} where wr_3 IN ($wridStr)";
    $result = sql_query($sql);
    $cnt = @mysqli_num_rows($result);
    if (!$cnt)
        alert("출력할 내역이 없습니다.");

    /*================================================================================
    php_writeexcel http://www.bettina-attack.de/jonny/view.php/projects/php_writeexcel/
    =================================================================================*/

    include_once(G5_LIB_PATH.'/Excel/php_writeexcel/class.writeexcel_workbook.inc.php');
    include_once(G5_LIB_PATH.'/Excel/php_writeexcel/class.writeexcel_worksheet.inc.php');

    include_once(G5_LIB_PATH.'/PhpOffice/Psr/autoloader.php');
	include_once(G5_LIB_PATH.'/PhpOffice/PhpSpreadsheet/autoloader.php');

    $fname = tempnam(G5_DATA_PATH, $board.".xls");
    $workbook = new writeexcel_workbook($fname);
    $worksheet = $workbook->addworksheet();

    // Put Excel data
    $data = array('HBL','MBL','상호','성명','사업자번호','우편번호','주소','전화번호','공급자상호','총중량','총포장갯수','출항지명','선기명','인도조건','통화종류','결재금액','취하사유','상품명','수량','단가','금액');
    $data = array_map('iconv_euckr', $data);
	$heading = $workbook->addformat(array('align' => 'center', 'bold' => 1, 'color' => 'black', 'border_color' => 'black'));
	$contents = $workbook->addformat(array('align' => 'center', 'color' => 'black', 'border_color' => 'black', 'num_format' => '0'));
	$contentsT = $workbook->addformat(array('color' => 'black', 'border_color' => 'black'));
	$contentsNum = $workbook->addformat(array('align' => 'center', 'color' => 'black', 'border_color' => 'black', 'num_format' => '1'));

    $col = 0;
    foreach($data as $cell) {
        $worksheet->write(0, $col++, $cell, $heading);
    }


    for($i=0; $row=sql_fetch_array($result); $i++)
    {

		for ($j=1; $j <= 30; $j++) {
			if (isset($row['wr_link'.$j]) && $row['wr_link'.$j])
				$row['linkCount']++;
		}

		for ($j=1; $j<=$row['linkCount']; $j++) {

	$k=$i+$j;
	(int)$wr_price[$j] = (int)$row['wr_link'.$j.'_etc1']*(int)$row['wr_link'.$j.'_etc2'];

        $row = array_map('iconv_euckr', $row);

		$up_date = date("y/m/d", strtotime($row['wr_datetime']));
		$worksheet->write($k, 0, $row['wr_subject'], $contentsNum);
		$worksheet->write($k, 1, $row['wr_3'], $contentsNum);
		$worksheet->set_column(0, 1, 20);

		$worksheet->write($k, 2, $row['wr_4'].$row['linkCount'], $contents);
		$worksheet->write($k, 3, $row['wr_4'].$k.'/'.$i.'/'.$j, $contents);
		$worksheet->set_column(2, 3, 16);
		$worksheet->write($k, 4, $row['wr_29'], $contents);
		$worksheet->set_column(4, 4, 16);
		$worksheet->write($k, 5, $row['wr_7'], $contentsNum);
		$worksheet->set_column(5, 5, 16);
		$worksheet->write($k, 6, $row['wr_8'], $contentsT);
		$worksheet->set_column(6, 6, 70);
		$worksheet->write($k, 7, $row['wr_6'], $contentsNum);
		$worksheet->set_column(7, 7, 16);

		$worksheet->write($k, 8, $row['wr_34'], $contents);
		$worksheet->set_column(8, 8, 16);
		$worksheet->write($k, 9, $row['wr_18'], $contents);
		$worksheet->write($k, 10, $row['wr_17'], $contents);
		$worksheet->set_column(9, 10, 16);

		$worksheet->write($k, 11, '', $contentsT);
		$worksheet->write($k, 12, $row['wr_38'], $contentsT);
		$worksheet->write($k, 13, 'FOB', $contentsT);
		$worksheet->write($k, 14, 'USD', $contentsT);
		$worksheet->write($k, 15, $row['wr_16'], $contents);
		$worksheet->write($k, 16, $row['wr_13'], $contents);

		$worksheet->write($k, 17, $row['wr_link'.$j], $contents);
		$worksheet->set_column(17, 17, 70);
		$worksheet->write($k, 18, $row['wr_link'.$j.'_etc1'], $contents);
		$worksheet->write($k, 19, $row['wr_link'.$j.'_etc2'], $contents);
		$worksheet->write($k, 20, $wr_price[$j], $contents);
		$worksheet->set_column(18, 20, 16);
		}

	}

    $workbook->close();
	
	header("Content-charset=utf-8");
    header("Content-Type: application/x-msexcel; name=\"Kor_Tariff-".date("ymd", time()).".xls\"");
    header("Content-Disposition: inline; filename=\"Kor_Tariff-".date("ymd", time()).".xls\"");
    $fh=fopen($fname, "rb");
    fpassthru($fh);
    unlink($fname);

    exit;
}

if (mysql_num_rows($result) == 0)
{
    echo "<script>alert('출력할 내역이 없습니다.'); window.close();</script>";
    exit;
}


페이지 소스는 이렇습니다.
리스트에서 체크한 자료를 내리는 것인데, 값에 특정 셀(wr_link1~30)에 값이 존재할 시 그에 해당하는 것들을 다운하는 페이지입니다.

for ($j=1; $j <= 30; $j++) {
if (isset($row['wr_link'.$j]) && $row['wr_link'.$j])
$row['linkCount']++;
}

for ($j=1; $j<=$row['linkCount']; $j++) {
이것은
wr_link1~30 에서
 중간에 비어 있는 경우가 절대 없어야 제대로 돌아가는 코드입니다.

출력하면 01 02 03 11 12 13 14 21 22 23 24 25 이런식으로 나와야 하는데
01 02 03 13 14 24 25 이렇게 출력이 되네요.
==
이 부분이 소스에서 어느 부분이죠?
==
이 부분은 엑셀로 출력했을 시 나오는 부분을 예시로 든 것입니다.
출력시 제대로나오는 보기위해 $i.'/'.$j 이부분이 추가해서 출력했을때 나오는 것인데요.
위의 숫자처럼 나와서 여쭤본거예요.

$worksheet->write($k, 3, $row['wr_4'].$k.'/'.$i.'/'.$j, $contents);
이 부분인가 보군요.
그런데 /가 안 찍히는 건가요?

$k=$i+$j;
이렇게 더한 값을 찍으면
말씀하시 대로 나오는 것이 정상 아닐까요?

값은 제대로 나옵니다. 다만 루프가 정상적으로 돌지않아서요.
첫번째 for에서 0 1 2를 뽑고 그 각각에 해당하는 값을 뽑는 것인데요.
0에 1 2, 1에 1 2 3 4 이런식으로 각각에 해당하는 셀이 있습니다.
정상적으로 나오면 01 02 11 12 13 14..... 이렇게 나와야 하는데 01 02 12 13.... 이런식으로 앞선 값에 영향을 받아서 11이 나오지않아서요.

$row['linkCount']=0; /////// 이렇게 초기화 해 주는 것이 좋습니다.
for ($j=1; $j <= 30; $j++) {
if (isset($row['wr_link'.$j]) && $row['wr_link'.$j])
$row['linkCount']++;
}

for ($j=1; $j<=$row['linkCount']; $j++) {

$k=$i+$j;
(int)$wr_price[$j] = ....
        //// =왼쪽에 (int)를 쓰는 것은 아무 의미가 없습니다.

        코드는 정상인 듯한데, 설명하시는 문제점을 이해하지 못하겠습니다.

계속 신경써주셔서 너무 감사합니다.
알려주신데로 초기화 코드 추가했습니다.

int를 쓴것은 안 쓸 경우 에러가 떠서 추가했습니다.

다시 설명을 드리자면
리스트에서 체크한 자료를 엑셀로 다운받는 것입니다.
그런데 그 체크한 자료 중 각각의 자료에는 wr_link1~wr_link30까지 값이 있는 것도 없는 것도 있습니다. 기본 그누보드는 wr_link2까지만 있습니다만 wr_link30까지 추가했습니다.

예를 들어, 체크한 자료가 wr_id1~wr_id3이고, 각각의 wr_id에는 wr_link1부터 wr_link3까지 자료가 있을 경우, 엑셀에 제목 등 정보 및 wr_link1부터 wr_link3까지의 내용이 각각 한줄로 루프 되어 세줄을 넣게되는 것입니다. wr_id1의 wr_link1 wr_link2 wr_link3, wr_id2의 wr_link1 wr_link2 wr_link3.... 이런식으로 총 9개의 자료가 엑셀로 출력되는 것이지요.

그런데 지금 현상은 wr_id1은 정상으로 나오나 wr_id2 이후부터는 앞쪽의 wr_link의 수를 영향을 받는 것인데요. 변수는 $j입니다.
wr_id1에서 $j의 마지막 값이 3일 경우 wr_id2에서는 $j가 3부터 시작한다는 것입니다.
그리고 다음 wr_id3에서도 $j가 wr_id2의 마지막 $j값부터 시작하는 것이구요.

설명을 잘 못해서 죄송합니다.

글쎄요.
$k=$i+$j;
$worksheet->write($k, ..
왜 cell 좌표를 $k로 하는지 이해가 안 가지만
==
wr_id1에서  $j의 마지막 값이 3일 경우
wr_id2에서는 $j가 3부터 시작한다는 것입니다.그리고 다음
wr_id3에서도 $j가 wr_id2의 마지막 $j값부터 시작하는 것이구요.
==
이 루프가 그렇게 돌지는 않게 보이네요.

$k=$i+$j; 로 한 이유는 $i는 리스트에서 체크한 숫자이고, $j는 각각에 해당하는 추가되는 경우입니다. 다른 방법이 있겠지만 간단하게 생각해서 제작했구요.

루프가 그렇게 돌지 않아야 하는데 결과물은 그렇게 돌고 있으니 저도 이해가 안되서 여쭤보는것입니다. 혹시 제가 놓친게 있지 않은가 해서요.

print로 결과값을 뽑아보니 쿼리나 루프상엔 문제가 없었습니다.
엑셀추출할때 문제가 생기는 부분이라 다르게 접근해야겠습니다.

이틀동안 같이 고민해 주셔서 감사합니다.

https://sir.kr/gujik/1290 에 저의 연락처가 있습니다

핸드폰으로 연락주시면 같이 고민 해드릴게요

아래에 $j 를 $l 로 수정해보세요.

 

    for($i=0; $row=sql_fetch_array($result); $i++)
    {

        for ($l=1; $l <= 30; $l++) {
            if (isset($row['wr_link'.$l]) && $row['wr_link'.$l])
                $row['linkCount']++;
        }

        for ($j=1; $j<=$row['linkCount']; $j++) {


    for ($i=0; $row=sql_fetch_array($result); $i++)
    {
        for ($j=0; $j < 30; $j++)
        {
            if (isset($row['wr_link'.$j+1]) && $row['wr_link'.$j+1])
                $row['linkCount']++;
        }
        for ($j=0; $j<$row['linkCount']; $j++)
        {
            $k = $i + $j;
            (int)$wr_price[$j] = (int)$row['wr_link'.$j+1.'_etc1']*(int)$row['wr_link'.$j+1.'_etc2'];
            /* ... 생략 ... */
            $worksheet->write($k, 17, $row['wr_link'.$j+1], $contents);
            $worksheet->set_column(17, 17, 70);
            $worksheet->write($k, 18, $row['wr_link'.$j+1.'_etc1'], $contents);
            $worksheet->write($k, 19, $row['wr_link'.$j+1.'_etc2'], $contents);
            $worksheet->write($k, 20, $wr_price[$j], $contents);
            $worksheet->set_column(18, 20, 16);
            /* ... 생략 ... */

변수에 계산식 넣으신($j+1) 에러나네요.
그리고 변수 $j시작을 1에서 0으로 -1 내리고 다른 변수부분에서 +1하는 것이 어떤 의미가 있는지 모르겠습니다. 이런 부분도 영향이 있을까요?
제가 잘 몰라서 여쭤보는 부분이니 설명해 주시면 감사하겠습니다.

다들 여러 답변을 위에 주셨는데요.. 지금은 보이지 않지만 쿼리를 보시면 잘못하셨을 겁니다. 

결과에 대한 답변을 드리자면...출력되는 내용은 숫자가 아니라 문자로 인식이 된것입니다.

 

> 출력하면 01 02 03 11 12 13 14 21 22 23 24 25 이런식으로 나와야 하는데

>  01 02 03 13 14 24 25 이렇게 출력이 되네요.   <-- 이것 문자로 인식을 하였다는것이지요..

 

개념만 알면 쉽습니다.

 

정렬를 문자로 인식할경우  -> 01 02 03 13 14 24 25

정렬를 숫자로  인식할경우 -> 1 2 3 13 14 24 25

 

요렇게 생각하면 쉽습니다.

쿼리에서 정렬을 하실때  숫자로 변경해서 정렬해보시기 바랍니다. 

 

숫자를 문자로 인식하면 무조건 앞자리가 우선입니다

 

예를들어 정렬 쿼리를 하신다면

>  select * from customers order by cast(customers_id as unsigned);

 

뒤에 cast를 사용해서 변경해서 정렬를 해보시기 바랍니다. 그럼 원하시는대로 순서적으로 정렬이 되실겁니다.

다만 해당 숫자  앞에 0값은 넣어주시면됩니다

첫번째 for, 즉 1 2 3에 따른 두번째 for는 첫번째에 해당하는 것에 대해 다시 정렬시키는 것입니다.

> 출력하면 01 02 03 11 12 13 14 21 22 23 24 25 이런식으로 나와야 하는데
>  01 02 03 13 14 24 25 이렇게 출력이 되네요.  <-- 이것 문자로 인식을 하였다는것이지요..

첫번째에서 돌때 0 1 2를 뽑고 0에 해당하는 1 2 3, 1에 해당하는 1 2 3 4..... 이런식으로 총 12개의 값이 나와야 하는데 7개만 뽑는 다는 것입니다. 그에 해당하는 문제가 발생하는 것이 j값이 이전의 j값에 영향을 받는 다는 것이구요. 말씀해주신 정렬순서상의 문제가 아닙니다.

답변을 작성하시기 전에 로그인 해주세요.
전체 123,674 | RSS
QA 내용 검색

회원로그인

(주)에스아이알소프트 / 대표:홍석명 / (06211) 서울특별시 강남구 역삼동 707-34 한신인터밸리24 서관 1404호 / E-Mail: admin@sir.kr
사업자등록번호: 217-81-36347 / 통신판매업신고번호:2014-서울강남-02098호 / 개인정보보호책임자:김민섭(minsup@sir.kr)
© SIRSOFT