diff --git a/ecrire/public/compiler.php b/ecrire/public/compiler.php
index 6ed69bf0a29dff751c4b8ae0903e0ef4f05fbc67..34127ef6d7245a26c75ab6c8b6f40647c639d090 100644
--- a/ecrire/public/compiler.php
+++ b/ecrire/public/compiler.php
@@ -719,9 +719,13 @@ function public_compiler_dist($squelette, $nom, $gram, $sourcefile, $connect='')
 				$boucles[$id]->type_requete = '';
 				$x = $boucles[$id]->sql_serveur;
 				$x = $x ? "$x:$type" : $type;
-				erreur_squelette(_T('zbug_table_inconnue',
-						    array('table' => $x )),
-						 $id);
+				// ne pas renvoyer d'erreur si la table est optionnelle
+				// declare par ? avant ) dans <BOUCLE_A(table ?)>
+				if (!$boucles[$id]->table_optionnelle) {
+					erreur_squelette(_T('zbug_table_inconnue',
+								array('table' => $x )),
+							 $id);
+				}
 			}
 		}
 	}
diff --git a/ecrire/public/interfaces.php b/ecrire/public/interfaces.php
index 2fdfd9b9770e5297c1aefbfab5bad8a6410574bf..c3a205805f151bc356709ca78982a9a47af5744d 100644
--- a/ecrire/public/interfaces.php
+++ b/ecrire/public/interfaces.php
@@ -44,6 +44,7 @@ class Boucle {
 	var $avant, $milieu, $apres, $altern;
 	var $lang_select;
 	var $type_requete;
+	var $table_optionnelle = false; # si ? dans <BOUCLE_x(table ?)>
 	var $sql_serveur = '';
 	var $param = array();
 	var $criteres = array();
diff --git a/ecrire/public/phraser_html.php b/ecrire/public/phraser_html.php
index 330c56a9e0a7292f7265e8a55705b406da422c04..1f527f1854eeca4be8256ff63ed6dfc6d510cdf6 100644
--- a/ecrire/public/phraser_html.php
+++ b/ecrire/public/phraser_html.php
@@ -25,7 +25,7 @@ define('BALISE_POST_BOUCLE', '</B');
 define('BALISE_ALT_BOUCLE', '<//B');
 
 define('TYPE_RECURSIF', 'boucle');
-define('SPEC_BOUCLE','/\s*\(\s*([^\s)]+)(\s*[^)]*)\)/');
+define('SPEC_BOUCLE','/\s*\(\s*([^\s?)]+)(\s*[^)?]*)([?]?)\)/');
 define('NOM_DE_BOUCLE', "[0-9]+|[-_][-_.a-zA-Z0-9]*");
 # ecriture alambiquee pour rester compatible avec les hexadecimaux des vieux squelettes
 define('NOM_DE_CHAMP', "#((" . NOM_DE_BOUCLE . "):)?(([A-F]*[G-Z_][A-Z_0-9]*)|[A-Z_]+)(\*{0,2})");
@@ -575,11 +575,16 @@ function public_phraser_html($texte, $id_parent, &$boucles, $nom, $ligne=1) {
                 $milieu = substr($milieu, strlen($match[0]));
 		$type = $match[1];
 		$jointures = trim($match[2]);
+		$table_optionnelle = ($match[3]);
 		if ($jointures) {
 			$result->jointures = preg_split("/\s+/",$jointures);
 			$result->jointures_explicites = $jointures;
 		}
-
+		
+		if ($table_optionnelle){
+			$result->table_optionnelle = true;	
+		}
+		
 		if ($p = strpos($type, ':'))
 		  {
 		    $result->sql_serveur = substr($type,0,$p);