To answer your question I had to create other tables that were not informed to get the nome_representante
and the nome_cliente
. And to do tests I created several records, see:
I put as optional the input value of the beginning of the year and the end of the year to be analyzed, because you may want to perform a filter. See the line below:
$anoInicio = "2017";
$anoFim = "2018";
Finally, I created the code based on yours. Note that select
is ordering, first by month, then by client code and then by year. This way you will get the expected result.
$anoInicio = "2017";
$anoFim = "2018";
$query = mysqli_query($conn, "SELECT ano, mes,
(
SELECT nome_cliente FROM cliente
WHERE cliente.codigo_cliente = clientes_vendas.codigo_cliente
) AS 'nome_cliente',
(
SELECT nome_representante FROM representante
WHERE representante.codigo_representante = clientes_vendas.codigo_representante
GROUP BY representante.codigo_representante
) AS 'nome_representante',
SUM(valor) AS 'total' FROM clientes_vendas
WHERE ano >= '$anoInicio' AND ano <= '$anoFim'
GROUP BY mes, codigo_cliente, ano ORDER BY codigo_cliente, mes, ano ASC"
);
$arraDados = array();
$strTmpCliente = "";
$mes = array('', 'Jan', 'Fev', 'Mar', 'Abr', 'Mai', 'Jun', 'Jul', 'Ago', 'Set', 'Out', 'Nov', 'Dez'); // formatador dos meses
$x = 1;
while($dados = mysqli_fetch_assoc($query)){
if($strTmpCliente != $dados['nome_cliente']){
$strTmpCliente = $dados['nome_cliente'];
$arraDados[$strTmpCliente] = array();
$arraDados[$strTmpCliente]['nome'] = $dados['nome_cliente'];
$arraDados[$strTmpCliente]['representante'] = $dados['nome_representante'];
}
$strMesAno = $mes[$dados['mes']]."_".$dados['ano'];
$arraDados[$strTmpCliente][$strMesAno] = number_format($dados['total'],2,",",".");
}
$header = "Cliente;Representante;";
$mesAtual = 1;
$anoAtual = (int)$anoInicio;
$arrayDatas = array();
for($x = 0; $x < 24; $x++){
$data = $mes[$mesAtual]."_".$anoAtual;
$arrayDatas[] = $data;
$header .= str_replace("_", "'",$data).";";
$alteraMes = $x % 2 == 0 ? false : true;
if($alteraMes){
$mesAtual++;
$anoAtual = $anoInicio;
continue;
}
$anoAtual = $anoFim;
}
$header = substr($header, 0, -1);
$header .= "\n";
$strDados = array();
foreach($arraDados as $cliente ){
$strTmp = $cliente['nome'].";".$cliente['representante'].";";
for($i = 0; $i < count($arrayDatas); $i++){
$data = $arrayDatas[$i];
if(isset($cliente[$data])){
$strTmp .= $cliente[$data].";";
continue;
}
$strTmp .= "-;";
}
$strTmp = substr($strTmp, 0, -1);
$strTmp .= "\n";
$strDados[] = $strTmp;
}
$csv = "arquivo.csv";
// escreve o cabeçalho
$fp1 = fopen($csv, 'w');
fwrite($fp1, $header);
fclose($fp1);
// escreve o resultado
$fp2 = fopen($csv, 'a');
foreach ($strDados as $file) {
fwrite($fp2, $file);
}
fclose($fp2);
The generated file was like this:
EDIT
I noticed that in the image that you posted that a few months were without sales. I went to take the test in my code and, as I imagined, it was a mistake. Because the values were filled sequentially.
I changed the code and now it is working correctly. I took the opportunity to insert the number_format
that you are using. The result was this:
EDIT 2
Change that part that will work:
if($strTmpCliente != $dados['nome_cliente']){
$strTmpCliente = $dados['nome_cliente'];
$arraDados[$strTmpCliente] = array();
$arraDados[$strTmpCliente]['nome'] = $dados['nome_cliente'];
$arraDados[$strTmpCliente]['representante'] = $dados['nome_representante'];
}
//---> o erro estava aqui
$dadosMes = (int)$dados['mes']; // aqui ele transforma em inteiro
$strMesAno = $mes[$dadosMes]."_".$dados['ano']; // aqui ele grava a strinmg corretamente
$arraDados[$strTmpCliente][$strMesAno] = number_format($dados['total'],2,",",".");
all clients have unique cnpjs or can repeat themselves? or is there another unique id index in your table?
– AnthraxisBR
only the code is unique Anthraxisbr
– denis
What I don’t understand is that in the image of the expected result shows, IN THE SAME LINE =>
1, 2017, valor
-1, 2018, valor
-2, 2017, valor
. Is that what you want? Because?– Andrei Coelho
What is the relationship? I don’t understand.
O primeiro é o mês de janeiro de 2017, depois é janeiro 2018 e depois é fevereiro de 2017. A logo abaixo começa com janeiro de 2017, depois janeiro de 2018(outro valor), e fevereiro de 2018.
– Andrei Coelho
@Have you ever thought about doing a treatment similar to what you are doing this year? the code is unique per client,code will start at zero,in the 1st interaction makes the completion of the 1st line with the information for ex: $line=$cnpj_client;...;$mes;$year;$value; in the next interaction if the code is equal you continue concatenating only the month data,year, value, $line.= $mes;$ano;$valor; and so it goes, until a different code comes, with that $line .= $pular_line and stores in the output array.start $line again, updating the code ,putting the "header" as in the first interaction and etc..
– Marcus Italo
@Andreicoelho Coelho I edited the image that was not clear ! the header doesn’t just need the results
– denis
Now I understand!
– Andrei Coelho
I will analyze @Marcusitalo Italo thank you.
– denis