RESOLU - Problème Exports

Bonjour,

Je suis en train de contruire un nouvel export avec un champ calculé, mais j’ai trouvé dans le code de la classe Export ce que je pense être un bug :

htdocs/exports/class/export.class.php : (line 207)

	function build_sql($indice, $array_selected, $array_filterValue)
	{
		// Build the sql request
		$sql=$this-\>array_export_sql_start[$indice];
		$i=0;

		//print_r($array_selected);
		foreach ($this-\>array_export_fields[$indice] as $key =\> $value)
		{
			if (! array_key_exists($key, $array_selected)) continue;		// Field not selected

			if ($i \> 0) $sql.=', ';
			else $i++;
			$newfield=$key.' as '.str_replace(array('.', '-'),'_',$key);;

			$sql.=$newfield;
		}
		$sql.=$this-\>array_export_sql_end[$indice];

		//construction du filtrage si le parametrage existe
		if (is_array($array_filterValue))
		{
			$sqlWhere='';
			// pour ne pas a gerer le nombre de condition
			foreach ($array_filterValue as $key =\> $value)
			{
				$sqlWhere.=" and ".$this-\>build_filterQuery($this-\>array_export_TypeFields[0][$key], $key, $array_filterValue[$key]);
			}
			$sql.=$sqlWhere;
		}

L’ajout du champ se fait uniquement avec la variable $key (et pas $value qui pourrait être l’alias SQL non ???).

Ceci se traduit pas l’impossibilité de mettre un champ calculé (erreur SQL), car alors dans le SQL généré nous avons : ifnull(…) as ifnull(…)

Exemple avec ma requête :

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '(concat(u_firstname, ' ', u_name),concat(u2_firstname, ' ', u2_name)), c.rowid a' at line 1 \- sql=SELECT DISTINCT s.rowid as s_rowid, s.nom as s_nom, s.address as s_address, s.cp as s_cp, s.ville as s_ville, cp.code as cp_code, s.tel as s_tel, ifnull(concat(u.firstname, ' ', u.name),concat(u2.firstname, ' ', u2.name)) as ifnull(concat(u_firstname, ' ', u_name),concat(u2_firstname, ' ', u2_name)), c.rowid as c_rowid, c.ref as c_ref, c.ref_client as c_ref_client, c.fk_soc as c_fk_soc, c.datec as c_datec, c.datep as c_datep, c.fin_validite as c_fin_validite, c.remise_percent as c_remise_percent, c.total_ht as c_total_ht, c.total as c_total, c.fk_statut as c_fk_statut, c.note as c_note, c.date_livraison as c_date_livraison, pcf.avancement as pcf_avancement, pcf.commande as pcf_commande, pcf.statut as pcf_statut, pcf.version as pcf_version FROM llx_societe as s LEFT JOIN llx_c_pays as cp ON s.fk_pays = cp.rowid LEFT JOIN llx_societe_commerciaux as sc ON s.rowid = sc.fk_user LEFT JOIN llx_user as u ON sc.fk_user = u.rowid, llx_propal as c LEFT JOIN llx_propal_customfields as pcf ON c.rowid = pcf.fk_propal, llx_user as u2 WHERE c.fk_soc = s.rowid AND c.fk_user_author = u2.rowid AND c.entity = 1 and date_format(c.datep,'%Y') = 2013

où l’on voit que le champ calculé devient

ifnull(concat(u.firstname, ' ', u.name),concat(u2.firstname, ' ', u2.name)) AS ifnull(concat(u_firstname, ' ', u_name),concat(u2_firstname, ' ', u2_name))

Cyril.

$value contient non pas un alias mais le nom du champ (et pour être plus précis sa traduction, c’est bien $key qu’il faut utiliser

Si tu souhaites utiliser des champs calculés il faudrait faire de la manière suivante

1 - définir dans le tableau export_fields_array le champ calculé de cette manière :

's.nom & " " & s.prenom as monchampcalcule'=\>'CompanyName',

2 - remplacer dans htdocs/exports/class/export.class.php la ligne

$newfield=$key.' as '.str_replace(array('.', '-'),'_',$key);;

par

[code type=php]$newfield=$key;

if (strpos($key, " as ") == 0)
$newfield.= ’ as ‹ .str_replace(array( ›.’, ‹ - ›),’_’,$key);[/code]

Cela pourrait faire l’objet d’une évolution du module export intéressante, je me le note dans un coin…

Merci beaucoup…

Avant de corriger cette classe ainsi, quelle est la méthode pour utiliser une chaine SQL directement à la place des tableaux (même si je me doute que ce n’est pas la meilleure méthode)

Cyril.

Bon, je viens de corriger cette classe, le sql généré est correct semble-t-il car le champ calculé est correctement rempli, mais je ne retrouve rien dans le fichier généré pour cette colonne…

Il s’agit probablement d’un problème de récupération de la colonne nommée, mais j’ai beau activer les logs je ne vois rien de spécial… :-/

Cyril

Un peu plus d’infos, j’ai ajouté des logs dans le module Excel2007 d’export :

Excel2007::write_record ifnull(concat(u.firstname, ' ', u.name),concat(u2.firstname, ' ', u2.name)) as commercial, 7, ifnull(concat(u_firstname, ' ', u_name),concat(u2_firstname, ' ', u2_name)) as commercial, 
Excel2007::write_record c.ref, 8, c_ref, SP/1212-00602-V1
      

Ce qui me montre que de mettre un alias ne suffit pas, la méthode système PHP mysqli_fetch_object ne connait pas cet alias, mais seulement « commercial » dans le SQL.

Je sèche là !

Une idée serait appréciée :happy:

Cyril

Allez hop, j’ai trouvé :happy:

Fichier core/module/export/export_excel2007.modules.php (ligne 279):
Remplacer :

	$alias=str_replace(array('.','-'),'_',$code);

par

	if( strpos($code, ' as ') == 0) { 
		$alias=str_replace(array('.','-'),'_',$code);
	}
	else {
		$alias=substr($code, strpos($code, ' as ') \+ 4);
	}

A Plus.

1 « J'aime »

Good works guys. I try to add changes into code.

Merci Eldy,

J’ai mis l’exemple pour Excel 2007, mais je pense qu’il faut faire pareil pour les 3 autres existants.

Cyril

Bonjour,
J’ai un problème identique, mais sur une constante dans la chaine SQL, vers un fichier EXCEL :

Je cherche à efféctuer un total sur l’export des écritures
Pour cela, j’ai ajouté dans dans la requête :
$totaux = « =INDEX(E:E;Ligne();0)-INDEX(D:D;LIGNE();0)+SI(ESTNUM(INDEX(G:G;LIGNE()-1;0));INDEX(G:G;LIGNE()-1;0);0) »;

puis ‹ ".$totaux." › as Solde" dans la requête.

Tout fonctionne très bien lorsque $totaux ne contient pas de caractères ‹ , ; : ›
Y a t-il moyen de voir ou l’erreur se produit ?

Merci
Voici le code en PJ: