Kirjautuminen

Haku

Tehtävät

Keskustelu: Nettisivujen teko: HTML taulukon muodostaminen

Sivun loppuun

mkl76 [30.06.2022 18:14:38]

#

Moi,


Yritän rakentaa HTML-taulukkoa, hyödyntäen PHP/SQL. Ohessa koodi:

<?php
$stid = oci_parse($conn, "select distinct concat(concat(order_no, '_'), sequence_no) from database
where order_no LIKE 'M114244' and release_no = '1'");
oci_execute($stid);

$stid2 = oci_parse($conn, "select oper_status_code from database
where order_no LIKE 'M114244' and release_no = '1' and operation_no = '22'");
oci_execute($stid2);
?>

<table style=" width: 60%; text-align: left; position: absolute; top:220px; left:440px; font-size: 10px;">
<tbody>
<tr>
<th>ORDER</th></td><th>STAGE</th></td>
</td>
<?php
while (($row = oci_fetch_array($stid, OCI_BOTH))) {

foreach ($row as $item) {
echo '</tr><td>'.($row[0]).'</td>';
}}

while (($row = oci_fetch_array($stid2, OCI_BOTH))) {

foreach ($row as $item) {
echo '</td><td>'.($row[0]).'</td>';
}}
?>

</tbody>
</table>

Saan tulokseksi tietyn määrän M-numeroja, jotka muodostuvat tulostetun taulukon sarakkeeseen sinänsä oikein mutta jostain syystä duplikaattina. Sen sijaan oper_status_code- sarakkeen tiedot tulostuvat HTML-taulukon alimmalle riville vaakatasossa.

Tähän tyyliin:

M114244_3
M114244_3
M114244_2
M114244_2
M114244_1
M114244_1 SULJETTU SULJETTU SULJETTU SULJETTU SULJETTU SULJETTU

Koodin tulostus tulisi siis olla näin:

M114244_1 SULJETTU
M114244_2 SULJETTU
M114244_3 SULJETTU

Lopullisena tarkoituksena olisi lisää noita vaihetietoja ja lisätä niiden tietoa seuraaviin sarakkeisiin. Esim. näin:

M114244_1 SULJETTU ALOITETTU
M114244_2 SULJETTU ALOITETTU
M114244_3 SULJETTU ALOITETTU

Pääsettekö kiinni ongelmaani, kaikki apu olisi tervetullutta.

PetriKeckman [30.06.2022 18:33:05]

#

Jokaista solua ennen tulostetaan '<td>' ja solun jälkeen '</td>' Samoin jokaista riviä, missä on noita soluja sitten, ennen tulostetaan '<tr>' ja noiden rivillä olevien solujen jälkeen taas '</tr>'. Onko sulla nää ehdot voimassa?

Rakenne pitäisi olla siis jotakuinkin:

<table>
<tr>
  <td>solu1</td>
  <td>solu2</td>
</tr> /*suljetaan eka rivi */
<tr> /*aloitaan uus rivi */
  <td>solu3</td>
  <td>solu4</td>
</tr>
</table>

mkl76 [05.07.2022 19:32:25]

#

Kiitos Petri,


Pääsin hieman eteenpäin.
Perehdyn hieman lisää ja saatan kysyä jatkokysymyksiä:)

PetriKeckman [05.07.2022 21:26:42]

#

mkl76 kirjoitti:

Kiitos Petri

Kiitti kiitoksesta.
Tässä vielä RED-kielinen esimerkki. Homma hoituu siis kahdella sisäkkäisellä silmukalla. Ulommassa loopataan rivejä ja sisemmässä datoja...Koodirivit kannattaa sisentää, niin sieltä näkee helpommin, mihin niitä datojen ja rivien lopetus- ja aloitus tägejä pitää laittaa.

Siis tällä koodilla tulee tälläinen: https://petke.info/taulukko.html

Red[]
rivienlkm: 4 ;	rivejä on 4 kpl
datojenlkm: 6 ;joka rivillä on 6 data alkiota
rivi: 1
print "<table>"
loop rivienlkm [
	print "<tr>"
	data: 1
	loop datojenlkm [
		print "<td>"
			print rejoin ["Solu " rivi "_" data]
		print "</td>"
		data: data + 1
	]
	print "</tr>"
	rivi: rivi + 1
]
print "</table>"
halt

Metabolix [05.07.2022 22:32:42]

#

L-kirjaimen muotoisen ongelman ydin on (HTML-virheen lisäksi) siinä, että HTML:ssä ei voi tulostaa taulukkoa sarake kerrallaan, vaan taulukko tehdään rivi kerrallaan. Eli PHP:ssä ei voi olla erillistä silmukkaa kummallekin sarakkeelle. Tiedot pitää järjestää tai hakea eri tavalla, jotta samassa silmukassa saa tulostettua molemmat sarakkeet.

Datan kahdentuminen johtuu siitä, että yksi tulosrivi (eli yksi arvo, koska SQL-kyselyissä haetaan vain yksi sarake) haetaan asetuksella OCI_BOTH, joka luo $row-taulukkoon sarakkeet sekä nimillä että numeroilla, esimerkiksi siis oper_status_code ja 0, ja sitten foreach-silmukassa tulostetaan nämä molemmat. Pitäisi siis luopua foreach-silmukasta ja tulostaa vain $row-taulukon kohta 0.

Tuo koko rakennelma on riskialtis, kun haetaan useampi asia omilla kyselyillään ja oletetaan, että tulosrivit ovat täsmälleen samat. Yleensä olisi järkevää muotoilla kysely niin, että kaikki tulosrivit saa samalla kyselyllä, tai sitten tuloksiin kannattaa sisällyttää ainakin riittävät tiedot, jotta yhteen kuuluvat tiedot pystyy varmuudella yhdistämään toisiinsa ennen tulostusta.

mkl76 [05.07.2022 22:37:19]

#

Minulla on nyt tällainen tuotos, koodi:

<table style=" width: 60%; text-align: left; position: absolute; top:220px; left:440px; font-size: 10px;">
    <tbody>
	<tr>
	<th>ORDER</th><th>REL</th><th>SEQ</th><th>VAIHE 1</th><th>VAIHE 2</th>
	</tr>
<?php

while (($row = oci_fetch_array($stid2, OCI_BOTH))) {
  echo '<tr><td>'.$row[0].'</td>';
  echo '<td>'.$row[1].'</td>';
  echo '<td>'.$row[2].'</td>';
  echo '<td>'.$row[48].'</td>';

while (($row = oci_fetch_array($stid3, OCI_BOTH))) {
  echo '<td>'.$row[0].'</td>';

}}

?>

</tbody>
</table>

Jälkimmäinen looppi ei tulosta vaihetietoja taulukon viimeiseen sarakkeeseen. Pääsetkö kiinni tuohon ilman tulosteen tarkempaa kuvausta. Ylempi looppi tulostaa haetut tiedot taulukkoon aivan kuten haluankin mutta alemman loopin lisäys rikkoo taulukon rakenteen. Tänne kun ei voi lisätä kuvaa ongelman selventämiseksi.

Metabolix [05.07.2022 22:42:41]

#

Oletko katsonut, mitä tuosta tulee sivun HTML-koodiksi? Eli nythän sinulla on kaksi silmukkaa sisäkkäin. Taulukon ensimmäisen rivin loppuun tulostat peräkkäin kaikki viimeisen sarakkeen arvot (vierekkäin eikä allekkain, koska näin HTML:n taulukko toimii), ja myöhemmille riveille ei jää viimeiseen sarakkeeseen mitään.

Periaatteessa tuo toimii, jos jälkimmäisen while-silmukan tilalle laitat if-lauseen, mutta varoituksena lue silti edellisen viestini viimeinen kappale.

mkl76 [05.07.2022 22:44:15]

#

Metabolix kirjoitti:

(05.07.2022 22:32:42): L-kirjaimen muotoisen ongelman ydin on (HTML...

Jep, asiallista kommenttia. Olenkin jo poistanut foreach- silmukat ja vienyt koodia juuri tuohon kirjoittamaasi suuntaan. Silmukat on itselle vielä hieman hepreaa. Tuon kyselyn kun saisikin yhteen ja samaan kyselyyn mutta en ole siinä vielä onnistunut kun rajatut tiedot pitää vielä saada tulostettuakin taulukkoon. Kyselyn laajentaminen sisältämään enemmän tietoa kun tuppaa omilla koodaustaidoilla tulostelemaan taulukkoon ylimääräistä tietoa.

mkl76 [07.07.2022 18:48:34]

#

Metabolix kirjoitti:

(05.07.2022 22:42:41): Oletko katsonut, mitä tuosta tulee sivun HTML...

Voiko if-lausetta käyttää while sijaan koska if pyörähtää vain yhden kerran?

Metabolix [07.07.2022 19:32:07]

#

Mutta nythän juuri tarkoitus olisi saada jokaiselle riville jälkimmäisestä kyselystä vain yksi tulos. Taulukkosi on pielessä juuri siksi, että while hakee kaikki jälkimmäisen kyselyn tulokset jo ensimmäiselle taulukon riville.

mkl76 [11.07.2022 15:22:13]

#

Metabolix kirjoitti:

Mutta nythän juuri tarkoitus olisi saada jokaiselle riville jälkimmäisestä kyselystä vain yksi tulos. Taulukkosi on pielessä juuri siksi, että while hakee kaikki jälkimmäisen kyselyn tulokset jo ensimmäiselle taulukon riville.

En saa tätä toimimaan. Olisiko sinulla kiinnostusta pureutua tähän aiheeseen esimerkkien kera, vaikka pientä korvausta vastaan? Kenties joku etäkeskustelu esim. Teams tms.?

Grez [11.07.2022 16:15:00]

#

Jotenkin tälleen alkuperäisen viestin ongelma voisi tuolla tietorakenteella toimia.

<?php
	$stid = oci_parse($conn, "select distinct concat(concat(order_no, '_'), sequence_no)
		from database
		where order_no LIKE 'M114244' and release_no = '1'
		order by order_no, sequence_no");
	oci_execute($stid);

	$stid2 = oci_parse($conn, "select concat(concat(order_no, '_'), sequence_no), oper_status_code
		from database
		where order_no LIKE 'M114244' and release_no = '1' and operation_no = '22'
		order by order_no, sequence_no");
	oci_execute($stid2);
?>

<table style=" width: 60%; text-align: left; position: absolute; top:220px; left:440px; font-size: 10px;">
<tbody>
  <tr>
  <th>ORDER</th><th>STAGE</th>
  </tr>
<?php
$stat = oci_fetch_array($stid2, OCI_NUM);
while ($row = oci_fetch_array($stid, OCI_NUM)) {
	echo '<tr><td>'.$row[0].'</td><td>';
	while ($stat && $stat[0]==$row[0]) {
		echo $stat[1] . ' ';
		$stat = oci_fetch_array($stid2, OCI_NUM);
	}
	echo '</td></tr>';
}
?>
</tbody>
</table>

Olennaiset muutokset kyseylyissä on, että myös jälkimmäisessä kyselyssä on otettu order_no ja sequence_no ja järjestetty molemmat sen mukaan, jotta tiedetään että ne tulee keskenään samassa järjestyksessä.

Tämähän nyt on hirveä purkkaviritys, mutta kun tietokantarakennekin näyttää olevan purkkaviritys (kaikki samassa database nimisessä taulussa, tilaukset toistettuna ilmeisesti niin monta kertaa kuin on tapahtumia, jne), niin ehkä se sopii.

Jälkimmäiseen 05.07.2022 22:37:19 laitettuun viestiin en nyt ala heittämään arvailuja, kun siinä ei edes näy kyselyitä eikä näin ollen pysty päättelemään mitään siitä miten sidosten ehkä olisi tarkoitus toimia.

mkl76 [12.07.2022 17:49:38]

#

Grez kirjoitti:

(11.07.2022 16:15:00): Jotenkin tälleen alkuperäisen viestin ongelma...

Juu, tuossa taulussa on paljon tietoa, käytännössä samalle tilaukselle ja rivinumerolle (sequence_no) voi olla 7-10 eri vaihetta ja näiden kanssa pitäisi pärjätä.

Koodin kyselyt on nyt ao. muodossa. Tilausnumerot muodostuu hyvin järjestyksessä HTML- taulun sarakkeeseen 1 ja vaiheen 20 tiedot seuraa hyvin perässä sarakkeeseen 2. Seuraavaksi pitäisi saada vaiheen nro. 22 tiedot seuraavaan sarakkeeseen nro. 3.

<?php
$stid = oci_parse($conn, "select concat(concat(order_no, '_'), sequence_no) from database
where order_no LIKE 'M114244' and release_no = '1'
group by concat(concat(order_no, '_'), sequence_no)
order by concat(concat(order_no, '_'), sequence_no)");
oci_execute($stid);

$stid2 = oci_parse($conn, "select concat(concat(order_no, '_'), sequence_no), oper_status_code from database
where order_no = 'M114244' and release_no = '1' and operation_no = '20'
group by concat(concat(order_no, '_'), sequence_no), oper_status_code
order by concat(concat(order_no, '_'), sequence_no), oper_status_code");
oci_execute($stid2);

$stid3 = oci_parse($conn, "select concat(concat(order_no, '_'), sequence_no), oper_status_code from database
where order_no = 'M114244' and release_no = '1' and operation_no = '22'
group by concat(concat(order_no, '_'), sequence_no), oper_status_code
order by concat(concat(order_no, '_'), sequence_no), oper_status_code");
oci_execute($stid3);
?>

Eli tämä pitäisi seuraavaksi ymmärtää ja muokata kolmannen sarakkeen tulostamiseksi:

$stat = oci_fetch_array($stid2, OCI_NUM);
while ($row = oci_fetch_array($stid, OCI_NUM)) {
	echo '<tr><td>'.$row[0].'</td><td>';
	while ($stat && $stat[0]==$row[0]) {
		echo $stat[1] . ' ';
		$stat = oci_fetch_array($stid2, OCI_NUM);
	}
	echo '</td></tr>';
}

Metabolix [12.07.2022 21:54:01]

#

Onko tiedot jostain syystä pakko hakea kesken tulostuksen? Olisi helpompaa kerätä niistä ensin yksi PHP-taulukko ja sitten vasta tulostaa.

$data = [];

// Kerää kaikkien kyselyiden tulokset $data-taulukkoon näin:
$stid = oci_parse($conn, "SELECT ...");
oci_execute($stid);
while ($row = oci_fetch_array($stid, OCI_NUM)) {
  // $row[0] on se yhteinen tunniste eli concat(...)
  // $row[1] on kyselyn toinen sarake eli esimerkiksi oper_status_code.
  $data[$row[0]][] = $row[1];
}

// Tulostus:
echo "<table>\n";
foreach ($data as $key => $row) {
  echo "<tr>\n";
  echo "<td>", htmlspecialchars($key), "</td>\n";
  foreach ($row as $col) {
    echo "<td>", htmlspecialchars($col), "</td>\n";
  }
  echo "</tr>\n\n";
}
echo "</table>\n";

muuskanuikku [12.07.2022 22:20:57]

#

Edellistä viestiä toistaen: tuollainen komentojen suorittaminen kesken tulostuksen on ns. vanhakantaista PHP:tä eli paskaa koodia. Hae tiedot ensin ja suorita tulostus joskus myöhemmin. Tämä helpottaa myös debuggaamista, koska voit tällöin vaikka dumpata haetun datan minne tahansa HTML-dokumentissa.

Jos yrität debugata tuota paskaa koodiasi, niin se on vaikeampaa jo siitä syystä, että selain saattaa renderöidä tulosteen ihan eri tavalla kuin mitä se on lähdekoodissa. (Ongelman voi toki kiertää katsomalla raakaa tulostetta selaimen renderöimän näkymän sijaan, mutta siltikin tuloste voi olla vaikeaa lukea.)

mkl76 [12.07.2022 22:52:06]

#

muuskanuikku kirjoitti:

(12.07.2022 22:20:57): Edellistä viestiä toistaen: tuol­lai­nen...

Nämä kommentit ei edistä asian ratkaisemista vaikka koodi olisi kokonaisuudessaan iso paskakasa.

Grez [13.07.2022 09:12:20]

#

mkl76 kirjoitti:

Koodin kyselyt on nyt ao. muodossa. Tilausnumerot muodostuu hyvin järjestyksessä HTML- taulun sarakkeeseen 1 ja vaiheen 20 tiedot seuraa hyvin perässä sarakkeeseen 2. Seuraavaksi pitäisi saada vaiheen nro. 22 tiedot seuraavaan sarakkeeseen nro. 3.

No kai voisit soveltaa tuota aikaisemmin annettua ratkaisua. Katsot mitä siinä tehdään ja teet vastaavan toisellekin.

mkl76 kirjoitti:

Nämä kommentit ei edistä asian ratkaisemista vaikka koodi olisi kokonaisuudessaan iso paskakasa.

Ongelmanhan voi yleensä ratkaista monella tavalla. Metabolixin ehdottama tietojen lukeminen muistiin ensin ja taulukon muodostaminen vasta sitten voisi selkeyttää asiaa ja sen toteuttamisessa ei montaa minuuttia pitäisi kestää.

mkl76 [20.07.2022 15:00:24]

#

Metabolix kirjoitti:

(12.07.2022 21:54:01): Onko tiedot jostain syystä pakko hakea kesken...

Tähän asti pyörittelemäni koodinpätkissä olen tosiaan hakenut ja tulostellut pienissä erissä. Nyt kuitenkin yo. esimerkin innostamana onnistuin muodostamaan laajemman kyselyn, jossa tarvittavat tiedot haetaan yhdellä kyselyllä ja ryhmitetään GROUP BY- ehdolla. Tämä ryhmittely on käsittääkseni ehdoton, koska muuten haetut tiedot leviää tulostuksen yhteydessä ihan miten sattuu. Testattu on.

<?php
$stid = oci_parse($conn, "select concat(concat(a.order_no, '_'), a.sequence_no), a.sarake1, a.sarake2, a.sarake3 from taulu1 a
FULL JOIN taulu2 b ON a.order_no = b.order_no and a.sequence_no = b.sequence_no
FULL JOIN taulu3 c ON a.order_no = c.order_no
where a.order_no LIKE 'M%' and a.release_no = '1' and 'lisää määrittelyjä tauluista 1,2 ja 3'
group by concat(concat(a.order_no, '_'), a.sequence_no), 'jne...'
order by concat(concat(a.order_no, '_'), a.sequence_no), 'jne'");



while ($row = oci_fetch_array($stid, OCI_NUM)) {
  // $row[0] on se yhteinen tunniste eli concat(...)
  // $row[1] on kyselyn toinen sarake eli esimerkiksi oper_status_code.
  $data[$row[0]][] = $row[1] ;
}

// Tulostus:

echo "<table>\n";
foreach ($data as $key => $row) {
  echo "<tr>\n";
  echo "<td>", htmlspecialchars($key), "</td>\n";
  foreach ($row as $col) {
    echo "<td>", htmlspecialchars($col), "</td>\n";
  }
  echo "</tr>\n\n";
}
echo "</table>\n";

?>

Nyt pitäisi saada vielä lisäopastusta kuinka valittuja sarakkeita tulostetaan HTML- taulukkoon, $row[2], $row[3] jne., kohdassa:

while ($row = oci_fetch_array($stid, OCI_NUM)) {
  // $row[0] on se yhteinen tunniste eli concat(...)
  // $row[1] on kyselyn toinen sarake eli esimerkiksi oper_status_code.
  $data[$row[0]][] = $row[1] ;
}

Metabolix [01.08.2022 13:22:52]

#

Yllä olevaan koodiin saat useamman sarakkeen samasta kyselystä näin:

$data[$row[0]][] = $row[1];
$data[$row[0]][] = $row[2];
# jne.

Tämä on tietysti ihan pöllö ratkaisu tilanteessa, jossa olet sittenkin tehnyt yhden kyselyn (alkuperäisen monen kyselyn viritelmän sijaan). Kuitenkin tämä on nyt lyhyin muutos, jolla saat nykyisen koodisi toimimaan.

Kaksi muuta vaihtoehtoa ovat, että opettelet PHP:tä kunnolla tai tilaat työt joltakulta, joka osaa sitä. Montako tuntia olet jo itse käyttänyt näiden parin koodirivin säätämiseen vain siksi, että yksinkertainen taulukko ja silmukka ovat vieraita?

mkl76 [02.08.2022 10:01:28]

#

Lienee syytä opetella kunnolla, jotta ei tarvitse näitä kysymyksiä foorumeille heitellä. Kiitoksia näistä vinkeistä, niistä oli paljon apua.


Sivun alkuun

Vastaus

Muista lukea kirjoitusohjeet.
Tietoa sivustosta