PHPExcel data checks - php

I'm trying to use PHPExcel to create a website that checks consistency of data in excel files.
I manage to load the excels but now I need to pass some checks on the data, and I can't figure out how. For example some of the checks would be:
Count number of empty cells in a specific column
Count number of non integer values in a specific column
Check that a column only has values that are contained in another one of the excels.
Are there some functions that do a kind of count where on the columns?
Or some way to iterate through the values to achieve this goals?
Thank you

Like Mark said, once I used PHPExcel to put the data into arrays I managed to do the checks myself. Here is an example of logging the empty cells of a column:
$n_row=0;
$divisasNull=0;
foreach ($sheetdata as $row) {
$n_column=0;
foreach ($row as $cell) {
if($n_column==6)
{
if($cell==null)
{
echo 'Error. Empty currency at row: '.$n_row.'<br>';
$divisasNull++;
}
}
$n_column++;
}
$n_row++;
}
echo 'Total errors: '.$divisasNull;

Related

Is it possible returning arrays from functions in php for-loop

The 1st for-loop is to retrieve $projSDE_1 which is employee ID and it's a value that changes every loop round.
$projSDE_1_IDs = [];
for($i=0; $i<db_rowcount();$i++)//1st for
{
$projSDE_1=db_get($i,8);
array_push($projSDE_1_IDs,$projSDE_1);
}
$projSDE_1_names = func_GetEmpNameNew($projSDE_1_IDs,$projSDE_1);
Next,the 2nd for-loop is going to retrieve all data and display it.All i need is each row will be able to display $projSDE_1_names by func_GetEmpNameNew($projSDE_1_IDs,$projSDE_1);
for($j=0; $j<db_rowcount();$j++)//2nd for
{
<tr >
<tbody>
<td style='width:5%'>".$no.". </a></td>
<td>".$projID." </td>
<td>".$projClient." </td>";
<td>".$projSDE_1_names." </td>";
</tbody>
</tr>
}//endfor
function to get $projSDE_1_names
function func_GetEmpNameNew($empIDs) {
$names = [];
foreach($empIDs as $empID){
$sqlEmp="select EmpID,LastName2_c from empbasic WHERE EmpID= '".$empID."'";
db_select($sqlEmp);
$rowcount=db_rowcount();
if(db_rowcount()>0){
for($f=0;$f<count($empIDs);$f++){
$empID=db_get($f,0);
$empName=db_get($f,1);
array_push($names, $empName);
}//for
}//if
}//foreach
return $names;
} // function
var_dump($projSDE_1_names); // Display the array to see if you get all the correct data.
The function is work fine and its able returns an array with the employees names..var_dump($projSDE_1_names);
So far this is the result i get - Result.
The list of name that displayed at the top is by
foreach ($projSDE_1_names as $projSDE_1_name) {
echo $projSDE_1_name.'-';
}
I need each name for each row.It listed 10 names from function and its suppose for 10 rows.All help appreciated
You are trying to fix the wrong issue.
Judging from your code, the initial list of values is retrieved from a relational database. The subsequent results are also retrieved from a relational database.
This alone is very wrong (unless the we are talking about 2 separate instances of DBMS which are unable to communicate directly). The right way to retrieve the 2 sets of data is using a JOIN on the data.
But that isn't the only howler in your code.
Repeatedly generating and executing a select statement in a loop is very bad practice. This would be solved by the same approach as the first issue above. However in the event of cases where the reference dataset does not originate on the same relational DBMS there are better ways to solve the problem. I would make a suggestion, but the db_ functions in your code are not standard PHP functions. The behaviour exposed in your code seems like a very cumbersome and limiting interface. Using mysqli you could simply....
function func_GetEmpNameNew($empIDs) {
global $db_handle;
$sqlEmp="select EmpID,LastName2_c from empbasic WHERE EmpID IN ("
. implode(",", $empID) // assuming the inputs are trusted and integer values
")";
$res=mysqli_query($db_handle, $sqlEmp);
return mysqli_fetch_all($res, MYSQLI_ASSOC);
}
As a side note you are using the order in which the data is returned in the orinal query as a means of indexing the result sets. As long as you are retrieving a single row each time, the data will matchup - but your code might retrieve zero, one or more than one row each time - again the solution is to run one query with a join. If you need to run queries against aseperate datasources, then index the array by a primary key attribute from the original dataset.

Dynamic Table Iteration PHP MySql

Suppose I have an SQL Statement that looks like:
SELECT * FROM myTable;
Now back in PHP I have a result array $result[], How can I iterate through that array and print out the values if I don't know the column names? Can I interrogate the array somehow?
Background: I have a table, I've rendered the table headings based on the a metadata table, now I need to populate the data, but I only want to pull out the field names that match the table headers and insert them into the HTML Table.
This process is happening dynamically, every table is different and has different field names (discovered by interrogating the metadata), but shares the same php code, so it needs to be flexible and smart enough to figure out what to render.
Edit: I now understand that your $result is an array of arrays.
foreach ($result as $row) {
foreach ($row as $key => $value) {
print "column $key has value $value\n";
}
}
Or you can call array_keys($row) to return the keys of an associative array.
You can use foreach loop with key-value pair in that case.
You can use it like this,
foreach($result as $key=>$value) {
//$key returns the key of $result array
//$value returns the respective value of that key
}

PHP spontaneously creates associative array where indexed array is required - using PHP arrays with Highcharts

I'm using PHP to retrieve data from an SQL database to produce a stacked column chart in Highcharts. The idea is that I'm taking the following piece of code to retrieve values from my database. This code should generate an array which then gets encoded to JSON and passed to Highcharts; this code produces a single 'part' of a stacked column, and the index determines which vertical bar that part is in. (So in http://www.highcharts.com/demo/column-stacked, the index would represent which fruit, and the data in this series would represent one person/color.)
The issue is that when I run this code, instead of ending up with an indexed array of data grouped by category, such as
[12,13,14,15] where each item is a category, I end up with an associative array where the indexes I specified in the code are turned into a string key.
{"1":13,"0":12,"3":14, "2":13, "5":15}
Because my indexes are being interpreted as associative keys and not as the indexed locations of the data inside the array, the data is now being added to locations in the order that I retrieved the data, and not assigned to a location in the array based on the index I give. Highcharts assigns categories based on location in the array, and not on key, so all my data ends up in the wrong categories.
Is there a way to get PHP to treat my carefully collected indexes as indexes and not as keys, and add my data points in the location in the array indicated by the indexes? I'm kind of new to PHP, and Java and C++ - the languages I've worked with before - don't have associative arrays, so any help you can give me in explaining and fixing this undesired behavior would be much appreciated.
Code below.
$variable indicates what the data is being sorted into categories by, and $r is the variable representing the array of the SQL query, so $r['variable'] is the category of this data point, and $r['amount'] is the data point itself.
$found = -1;
//if this is the first set of data being collected
if (count($category['data']) == 0){
$category['data'][0] = $r[$variable];
$series1['data'][0] = floatval($r['amount']);
$count++;
$times1[0]++;
}
//if it's not the first set of data, find out if this category has been used before
else {
for ($x = 0; $x < count($category['data']); $x++){
if ($r[$variable] == $category['data'][$x]){
$found = $x;
break;
}
}
// if that category does not already exist, add it, and add the data
if ($found == -1) {
$times1[$count]++;
$category['data'][$count] = $r[$variable];
$series1['data'][$count] = floatval($r['amount']);
$count++;
}
else { //otherwise, add its data to the data already in the current category. This will eventually yield an average, with $times1[] as the divisor
$times1[$found]++;
$series3['data'][$found] = floatval((floatval($series3['data'][$found]) + floatval($r['amount'])));
}}
Go through with below code hope it will give some idea to resolve your problem --
<?php
$jsonstring = '{"1":13,"0":12,"3":14, "2":13, "5":15}';
$tempArr = json_decode($jsonstring, true);
asort(tempArr); // for sorting the array --
//run another foreach to get created an array --
$finArr = array();
foreach(tempArr as $key=>$val){
$finArr[] = $val;
}
$requiredjsonString = json_encode(finArr); // it will return your required json Array [12,13,14,15]
?>
Edit: I advice also set JSON_NUMERIC_CHECK flag in json_encode();

Editing the object returned by $wpdb->get_results(SQL)

We have a nasty database call using the Wordpress function $wpdb->get_results(SQL).
After receiving the result in PHP, we need to make a few changes to the result.
So can anyone tell me how I can:
1) Remove specific rows from the get_results() returned object.
2) Change the values of the specific columns in specific rows in the returned object.
I.e. if the object returned is $nastyData, we need to:
1) Remove specific rows from $nastyData
2) Change the value of specific columns in specific rows in $nastyData, for example $nastyData->name for a specific row.
Any ideas?
I have thought about makeing get_results() return the data as an array, but that will create problems in other places in our code (where the code expects to receive an object).
Thanks,
Mads
To start with, your "Nasty database call" should be optimized to be less nasty. More specifically, only query the results you want so that you don't have to remove stuff afterwords. This is the best solution.
If you insist on trying to modify the objects, this is a workaround. According to the documentation, when returning objects, they are returned in one of two ways:
OBJECT - result will be output as a numerically indexed array of row objects.
OBJECT_K - result will be output as an associative array of row objects, using first column's values as keys (duplicates will be discarded).
So, knowing that the result is an array of objects, we can get to each individual instance using a foreach construct:
$results = $wpdb->get_results( $nastySQL );
foreach($results as $index => $result)
{
// Change name column to FirstName using copy and delete
$tmp = $result->name;
unset($result->name);
$result->FirstName = $tmp;
// Remove specific row
if( $result->name == "Tom")
{
unset($results[$index]);
}
}
Below code will replace the value coming from specific field of database table, if name field has value like Reo and you want to replace it with other name like John then you can to do this via below code
$results = $wpdb->get_results( $nastySQL );
foreach($results as $key => $value){
$results[$key]->name= 'John';
}
return $results;

PHP – Retrieving values from multi-dimensional arrays

I have a working script, but I'm sure that my method of managing arrays could be better. I've searched for a solution and haven't found one, but I'm sure that I should be using the functionality of associative arrays to do things more efficiently.
I have two arrays, one from a CSV file and one from a DB. I've created the CSV array as numeric and the DB array as associative (although I'm aware that the difference is blurry in PHP).
I'm trying to find a record in the DB array where the value in one field matches a value in the CSV array. Both arrays are multi-dimensional.
Within each record in each array there is a reference number. It appears once in the CSV array and may appear in the DB array. If it does, I need to take action.
I'm currently doing this (simplified):
$CSVarray:
('reference01', 'blue', 'small' ),
('reference02', 'red', 'large' ),
('reference03', 'pink', 'medium' )
$Dbarray:
(0 => array(ref=>'reference01',name=>"tom",type=>"mouse"),
(1 => array(ref=>'reference02',name=>"jerry",type=>"cat"),
(2 => array(ref=>'reference03',name=>"butch",type=>"dog"),
foreach ($CSVarray as $CSVrecord) {
foreach ($Dbarray as $DBrecord) {
if ($CSVarray[$numerickey] == $DBrecord['key'] {
do something with the various values in the $DBrecord
}
}
}
This is horrible, as the arrays are each thousands of lines.
I don't just want to know if matching values exist, I want to retrieve data from the matching record, so functions like 'array_search ' don't do what I want and array_walk doesn't seem any better than my current approach.
What I really need is something like this (gibberish code):
foreach ($CSVarray as $CSVrecord) {
WHERE $Dbarray['key']['key'] == $CSVrecord[$numerickey] {
do something with the other values in $Dbarray['key']
}
}
I'm looking for a way to match the values using the keys (either numeric or associative) rather than walking the arrays. Can anyone offer any help please?
use a hash map - take one array and map each key of the record it belongs to, to that record. Then take the second array and simply iterate over it, checking for each record key if the hashmap has anything set for it.
Regarding your example:
foreach ($DBarray as $DBrecord){
$Hash[$record[$key]] = $DBrecord;
}
foreach ($CSVarray as $record){
if (isset($Hash[$record[$CSVkey]])){
$DBrecord = $Hash[$record[$CSVkey]];
//do stuff with $DBrecord and $CSVrecord
}
}
this solution works at O(n) while yours at O(n^2)...
You can use foreach loops like this too:
foreach ($record as $key => $value) {
switch($key)
{
case 'asd':
// do something
break;
default:
// Default
break;
}
}
A switch may be what you are looking for also :)
Load CSV into the db, and use db (not db array) if possible for retrieval. Index the referenceid field.

Categories