<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Philben - Ms Access &#187; Requête SQL</title>
	<atom:link href="https://blog.developpez.com/philben/ptag/sql/feed" rel="self" type="application/rss+xml" />
	<link>https://blog.developpez.com/philben</link>
	<description></description>
	<lastBuildDate>Thu, 26 Sep 2013 19:43:53 +0000</lastBuildDate>
	<language>fr-FR</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.1.42</generator>
	<item>
		<title>Calcul direct de la date de Pâques en SQL</title>
		<link>https://blog.developpez.com/philben/p11430/sql-access/calcul-direct-de-la-date-de-paques-en-sql</link>
		<comments>https://blog.developpez.com/philben/p11430/sql-access/calcul-direct-de-la-date-de-paques-en-sql#comments</comments>
		<pubDate>Sat, 13 Oct 2012 19:44:07 +0000</pubDate>
		<dc:creator><![CDATA[philben]]></dc:creator>
				<category><![CDATA[SQL - Ms Access]]></category>
		<category><![CDATA[Algorithme]]></category>
		<category><![CDATA[Date]]></category>
		<category><![CDATA[Requête SQL]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/philben/?p=469</guid>
		<description><![CDATA[La requête paramétrée suivante calcule directement la date du Dimanche de Pâques entre 1900 et 2099 sans faire intervenir une fonction VBA personnelle grâce à une formule dérivée de l&#8217;algorithme de Carter. La date des 3 jours fériés mobiles français &#8230; <a href="https://blog.developpez.com/philben/p11430/sql-access/calcul-direct-de-la-date-de-paques-en-sql">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>La requête paramétrée suivante calcule directement la date du Dimanche de Pâques entre <strong>1900 et 2099</strong> sans faire intervenir une fonction VBA personnelle grâce à une formule dérivée de l&rsquo;algorithme de <strong>Carter</strong>.<br />
La date des 3 jours fériés mobiles français (Lundi de Pâques, Ascension et Lundi de Pentecôte) est également formulée, bien que le lundi de  Pentecôte ne soit plus chômé depuis 2005 (journée de solidarité).<br />
<span id="more-469"></span><br />
<strong>La requête SQL pour ACCESS</strong></p>
<div class="codecolorer-container sql blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">PARAMETERS Annee Short;<br />
<span style="color: #993333; font-weight: bold;">SELECT</span> IIF<span style="color: #66cc66;">&#40;</span>Annee <span style="color: #993333; font-weight: bold;">BETWEEN</span> <span style="color: #cc66cc;">1900</span> <span style="color: #993333; font-weight: bold;">AND</span> <span style="color: #cc66cc;">2099</span><span style="color: #66cc66;">,</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;DateSerial<span style="color: #66cc66;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Annee<span style="color: #66cc66;">,</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #cc66cc;">3</span><span style="color: #66cc66;">,</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">204</span> <span style="color: #66cc66;">-</span> <span style="color: #cc66cc;">11</span> <span style="color: #66cc66;">*</span> <span style="color: #66cc66;">&#40;</span>Annee <span style="color: #993333; font-weight: bold;">MOD</span> <span style="color: #cc66cc;">19</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">MOD</span> <span style="color: #cc66cc;">30</span> <span style="color: #66cc66;">+</span> <span style="color: #cc66cc;">28</span> <span style="color: #66cc66;">+</span> <span style="color: #66cc66;">&#40;</span>Annee <span style="color: #993333; font-weight: bold;">MOD</span> <span style="color: #cc66cc;">19</span> <span style="color: #993333; font-weight: bold;">IN</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">5</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">16</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">-</span> <span style="color: #66cc66;">&#40;</span>Annee <span style="color: #66cc66;">+</span> Annee \ <span style="color: #cc66cc;">4</span> <span style="color: #66cc66;">+</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">204</span> <span style="color: #66cc66;">-</span> <span style="color: #cc66cc;">11</span> <span style="color: #66cc66;">*</span> <span style="color: #66cc66;">&#40;</span>Annee <span style="color: #993333; font-weight: bold;">MOD</span> <span style="color: #cc66cc;">19</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">MOD</span> <span style="color: #cc66cc;">30</span> <span style="color: #66cc66;">+</span> <span style="color: #cc66cc;">22</span> <span style="color: #66cc66;">+</span> <span style="color: #66cc66;">&#40;</span>Annee <span style="color: #993333; font-weight: bold;">MOD</span> <span style="color: #cc66cc;">19</span> <span style="color: #993333; font-weight: bold;">IN</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">5</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">16</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">MOD</span> <span style="color: #cc66cc;">7</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">NULL</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #66cc66;">&#91;</span>Dimanche de Pâques<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">,</span> <br />
&nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#91;</span>Dimanche de Pâques<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">+</span> <span style="color: #cc66cc;">1</span> &nbsp;<span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #66cc66;">&#91;</span>Lundi de Pâques<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#91;</span>Dimanche de Pâques<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">+</span> <span style="color: #cc66cc;">39</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #66cc66;">&#91;</span>Ascension<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#91;</span>Dimanche de Pâques<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">+</span> <span style="color: #cc66cc;">50</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #66cc66;">&#91;</span>Lundi de Pentecôte<span style="color: #66cc66;">&#93;</span></div></div>
<p>&nbsp;<br />
<strong>Remarques</strong><br />
Si vous souhaitez extrapoler la formule à d&rsquo;autres SQL, il faut savoir que sous Access :</p>
<ul>
<li>True = -1 donc <code class="codecolorer sql blackboard"><span class="sql"><span style="color: #66cc66;">&#40;</span>Annee <span style="color: #993333; font-weight: bold;">MOD</span> <span style="color: #cc66cc;">19</span> <span style="color: #993333; font-weight: bold;">IN</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">5</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">16</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></span></code> retourne -1 si vrai;</li>
<li>L&rsquo;opérateur &lsquo;\&rsquo; de <code class="codecolorer sql blackboard"><span class="sql">Annee \ <span style="color: #cc66cc;">4</span></span></code> retourne seulement la partie entière de la division;</li>
<li>Attention aussi à la priorité des opérateurs&#8230;
</ul>
<p>Il n&rsquo;est pas possible non plus de copier directement la formule dans une fonction VBA car elle utilise des opérateurs spécifiques SQL (Between et In).<br />
&nbsp;<br />
<strong>Exemples</strong><br />
Au lancement de la requête, un popup demande de saisir l&rsquo;année souhaitée.</p>
<div class="codecolorer-container text geshi" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Dimanche &nbsp; &nbsp;Lundi de <br />
de Pâques &nbsp; Pâques &nbsp; &nbsp; &nbsp;Ascension &nbsp; Lundi de Pentecôte<br />
15/04/1900 &nbsp;16/04/1900 &nbsp;24/05/1900 &nbsp;04/06/1900<br />
18/04/1954 &nbsp;19/04/1954 &nbsp;27/05/1954 &nbsp;07/06/1954<br />
08/04/2012 &nbsp;09/04/2012 &nbsp;17/05/2012 &nbsp;28/05/2012<br />
21/04/2019 &nbsp;22/04/2019 &nbsp;30/05/2019 &nbsp;10/06/2019<br />
12/04/2099 &nbsp;13/04/2099 &nbsp;21/05/2099 &nbsp;01/06/2099</div></div>
<p>Si l&rsquo;année est en dehors de la plage 1900 &#8211; 2099, NULL est renvoyé pour chaque colonne.</p>
<p><strong>A noter</strong><br />
La formule pour le <a href="http://access.developpez.com/faq/?page=TAManip#NbJourOuvr" title="Comment calculer le nombre de jours ouvrables entre deux dates ?" target="_blank">calcul des jours ouvrables</a> de la <strong>FAQ Access</strong> n&rsquo;est valable que pour la période comprise entre <strong>1982 et 2048.</strong></p>
<p>@+</p>
<p>Philippe</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Transposer des lignes en une colonne</title>
		<link>https://blog.developpez.com/philben/p11320/vba-access/transposer-des-lignes-en-une-colonne</link>
		<comments>https://blog.developpez.com/philben/p11320/vba-access/transposer-des-lignes-en-une-colonne#comments</comments>
		<pubDate>Sun, 16 Sep 2012 08:34:58 +0000</pubDate>
		<dc:creator><![CDATA[philben]]></dc:creator>
				<category><![CDATA[SQL - Ms Access]]></category>
		<category><![CDATA[VBA - Ms Access]]></category>
		<category><![CDATA[Chaîne de caractères]]></category>
		<category><![CDATA[Code VBA]]></category>
		<category><![CDATA[Requête SQL]]></category>
		<category><![CDATA[Transposer]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/philben/?p=193</guid>
		<description><![CDATA[On a parfois besoin de concaténer dans une colonne le contenu de plusieurs lignes d&#8217;une table ou d&#8217;une requête. Par exemple, On part de : pour arriver à : Je vous propose une fonction écrite en VBA qui réalise cette &#8230; <a href="https://blog.developpez.com/philben/p11320/vba-access/transposer-des-lignes-en-une-colonne">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>On a parfois besoin de concaténer dans une colonne le contenu de plusieurs lignes d&rsquo;une table ou d&rsquo;une requête.<br />
<span id="more-193"></span><br />
<strong>Par exemple</strong>, On part de :<br />
<img src="http://philben.developpez.com/ConcatenationTable.png" alt="Concaténation de la table" /><br />
<br />
pour arriver à :<br />
<img src="http://philben.developpez.com/ConcatenationResultat.png" alt="Résultat de la concaténation" /><br />
<br />
Je vous propose une fonction écrite en VBA qui réalise cette transposition.</p>
<p><strong>Code de la fonction VBA</strong></p>
<div class="codecolorer-container vb blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:400px;"><div class="vb codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #008000;">'----------------------------------------------------------------------------------------------------------<br />
</span><span style="color: #008000;">' Procédure &nbsp; &nbsp;: ConcatColonne &nbsp; [Function]<br />
</span><span style="color: #008000;">' Retour &nbsp; &nbsp; &nbsp; : String<br />
</span><span style="color: #008000;">' Auteur &nbsp; &nbsp; &nbsp; : PhilBen - Free to use<br />
</span><span style="color: #008000;">' Version &nbsp; &nbsp; &nbsp;: 1.06<br />
</span><span style="color: #008000;">' Création/Maj : Samedi 15 septembre 2012<br />
</span><span style="color: #008000;">' Objet &nbsp; &nbsp; &nbsp; &nbsp;: Permet de concaténer en lignes les données d'une colonne en fonction d'un pivot<br />
</span><span style="color: #008000;">' Arguments &nbsp; &nbsp;: - ValeurPivot : La valeur de la colonne pivot<br />
</span><span style="color: #008000;">' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: - NomColonnePivot : Nom de la colonne pivot<br />
</span><span style="color: #008000;">' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: - NomColonneConcat : Nom de la colonne à concaténer<br />
</span><span style="color: #008000;">' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: - NomDomaine : Table ou requête des colonnes<br />
</span><span style="color: #008000;">' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: - Filtre : Permet d'appliquer un filtre supplémentaire sur le domaine (&quot;&quot; pour aucun)<br />
</span><span style="color: #008000;">' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: - RegrouperCompter : Regrouper (=1 ou &gt;0 et 2) ET Compter (=2) ou pas de regroupement (=0) des éléments concaténés<br />
</span><span style="color: #008000;">' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: - PasVideNULL : ne retourne pas les éléments concaténés vide &quot;&quot; et NULL (=True) sinon False<br />
</span><span style="color: #008000;">' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: - TriAscendant : Tri Ascendant (=True), Descendant (=False)<br />
</span><span style="color: #008000;">' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: - Separateur : String qui sépare les éléments concaténés (ex: &quot;,&quot;,&quot;---&quot;,...)<br />
</span><span style="color: #008000;">' Remarques &nbsp; &nbsp;: * Cette fonction ralentit sensiblement la requête :<br />
</span><span style="color: #008000;">' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-&gt; Meilleure performance si au moins la colonne pivot est indexée avec doublons<br />
</span><span style="color: #008000;">' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: * Le type de la colonne pivot peut être Date, numérique, string<br />
</span><span style="color: #008000;">' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: * Pour des raisons de performance, éviter de faire un filtre, un tri, <br />
</span><span style="color: #008000;">' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: &nbsp; un regroupement sur la colonne de concaténation, la déclarer si possible 'Expression' !<br />
</span><span style="color: #008000;">' Exemple &nbsp; &nbsp; &nbsp;: SELECT [MaColPivot],<br />
</span><span style="color: #008000;">' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: ConcatColonne([MaColPivot],&quot;MaColPivot&quot;,&quot;MaColConcat&quot;,&quot;MaTable&quot;,&quot;&quot;,1,True,True,&quot;, &quot;)<br />
</span><span style="color: #008000;">' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: FROM MaTable Group By [MaColPivot]<br />
</span><span style="color: #008000;">' Historique &nbsp; : 1.03 : Correction bug si le pivot est de type date<br />
</span><span style="color: #008000;">' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: 1.04 : Complément d'information dans l'en-tête de la fonction<br />
</span><span style="color: #008000;">' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: 1.05 : Correction bug si Pivot numérique avec décimales (, -&gt; .)<br />
</span><span style="color: #008000;">' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: 1.06 : Ajout compte des données regroupées + modification des paramètres (type et nom)<br />
</span><span style="color: #008000;">'----------------------------------------------------------------------------------------------------------<br />
</span><span style="color: #E56717; font-weight: bold;">Public</span> <span style="color: #E56717; font-weight: bold;">Function</span> ConcatColonne(<span style="color: #151B8D; font-weight: bold;">ByVal</span> ValeurColonnePivot <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Variant</span>, _<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #151B8D; font-weight: bold;">ByVal</span> NomColonnePivot <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span>, _<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #151B8D; font-weight: bold;">ByVal</span> NomColonneConcat <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span>, _<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #151B8D; font-weight: bold;">ByVal</span> NomDomaine <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span>, _<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #151B8D; font-weight: bold;">Optional</span> <span style="color: #151B8D; font-weight: bold;">ByVal</span> Filtre <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span> = vbNullString, _<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #151B8D; font-weight: bold;">Optional</span> <span style="color: #151B8D; font-weight: bold;">ByVal</span> RegrouperCompter <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Integer</span> = 1, _<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #151B8D; font-weight: bold;">Optional</span> <span style="color: #151B8D; font-weight: bold;">ByVal</span> PasVideNULL <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Boolean</span> = <span style="color: #00C2FF; font-weight: bold;">True</span>, _<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #151B8D; font-weight: bold;">Optional</span> <span style="color: #151B8D; font-weight: bold;">ByVal</span> TriAscendant <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Boolean</span> = <span style="color: #00C2FF; font-weight: bold;">True</span>, _<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #151B8D; font-weight: bold;">Optional</span> <span style="color: #151B8D; font-weight: bold;">ByVal</span> Separateur <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span> = <span style="color: #800000;">&quot;, &quot;</span>) <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span><br />
&nbsp; &nbsp;<span style="color: #151B8D; font-weight: bold;">On</span> <span style="color: #151B8D; font-weight: bold;">Error</span> <span style="color: #8D38C9; font-weight: bold;">GoTo</span> Catch<br />
&nbsp; &nbsp;<span style="color: #151B8D; font-weight: bold;">Dim</span> oDb <span style="color: #151B8D; font-weight: bold;">As</span> DAO.Database, oRs <span style="color: #151B8D; font-weight: bold;">As</span> DAO.Recordset, sSQL <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span><br />
<br />
&nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">If</span> <span style="color: #8D38C9; font-weight: bold;">Not</span> IsNull(ValeurColonnePivot) <span style="color: #8D38C9; font-weight: bold;">Then</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">If</span> RegrouperCompter = 2 <span style="color: #8D38C9; font-weight: bold;">Then</span> &nbsp; &nbsp; &nbsp;<span style="color: #008000;">'regrouper ET compter<br />
</span> &nbsp; &nbsp; &nbsp; &nbsp; sSQL = NomColonneConcat &amp; <span style="color: #800000;">&quot; &amp; &quot;</span><span style="color: #800000;">&quot; (&quot;</span><span style="color: #800000;">&quot; &amp; &quot;</span> &amp; <span style="color: #800000;">&quot;COUNT(*)&quot;</span> &amp; <span style="color: #800000;">&quot; &amp; &quot;</span><span style="color: #800000;">&quot;)&quot;</span><span style="color: #800000;">&quot; &amp; &quot;</span> &amp; <span style="color: #800000;">&quot;&quot;</span><span style="color: #800000;">&quot;&quot;</span> &amp; Separateur &amp; <span style="color: #800000;">&quot;&quot;</span><span style="color: #800000;">&quot; As C&quot;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">Else</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;sSQL = NomColonneConcat &amp; <span style="color: #800000;">&quot; &amp; &quot;</span><span style="color: #800000;">&quot;&quot;</span> &amp; Separateur &amp; <span style="color: #800000;">&quot;&quot;</span><span style="color: #800000;">&quot; As C&quot;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">If</span><br />
&nbsp; &nbsp; &nbsp; sSQL = <span style="color: #800000;">&quot;SELECT &quot;</span> &amp; sSQL &amp; <span style="color: #800000;">&quot; FROM &quot;</span> &amp; NomDomaine &amp; <span style="color: #800000;">&quot; WHERE &quot;</span> &amp; NomColonnePivot &amp; <span style="color: #800000;">&quot;=&quot;</span><br />
<br />
&nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">Select</span> <span style="color: #8D38C9; font-weight: bold;">Case</span> VarType(ValeurColonnePivot)<br />
&nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">Case</span> vbString<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;sSQL = sSQL &amp; <span style="color: #800000;">&quot;&quot;</span><span style="color: #800000;">&quot;&quot;</span> &amp; ValeurColonnePivot &amp; <span style="color: #800000;">&quot;&quot;</span><span style="color: #800000;">&quot;&quot;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">Case</span> vbDate<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;sSQL = sSQL &amp; Format(ValeurColonnePivot, <span style="color: #800000;">&quot;\#m-d-yyyy h:n:s\#&quot;</span>)<br />
&nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">Case</span> <span style="color: #8D38C9; font-weight: bold;">Else</span> &nbsp; <span style="color: #008000;">'Numériques<br />
</span> &nbsp; &nbsp; &nbsp; &nbsp; sSQL = sSQL &amp; Replace(ValeurColonnePivot, <span style="color: #800000;">&quot;,&quot;</span>, <span style="color: #800000;">&quot;.&quot;</span>)<br />
&nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">Select</span><br />
<br />
&nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">If</span> Filtre &lt;&gt; vbNullString <span style="color: #8D38C9; font-weight: bold;">Then</span> sSQL = sSQL &amp; <span style="color: #800000;">&quot; And &quot;</span> &amp; Filtre<br />
&nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">If</span> PasVideNULL = <span style="color: #00C2FF; font-weight: bold;">True</span> <span style="color: #8D38C9; font-weight: bold;">Then</span> sSQL = sSQL &amp; <span style="color: #800000;">&quot; AND LEN(NZ(&quot;</span> &amp; NomColonneConcat &amp; <span style="color: #800000;">&quot;))&gt;0&quot;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">If</span> RegrouperCompter &gt; 0 <span style="color: #8D38C9; font-weight: bold;">Then</span> sSQL = sSQL &amp; <span style="color: #800000;">&quot; GROUP BY &quot;</span> &amp; NomColonneConcat<br />
&nbsp; &nbsp; &nbsp; sSQL = sSQL &amp; <span style="color: #800000;">&quot; ORDER BY &quot;</span> &amp; NomColonneConcat<br />
&nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">If</span> <span style="color: #8D38C9; font-weight: bold;">Not</span> TriAscendant <span style="color: #8D38C9; font-weight: bold;">Then</span> sSQL = sSQL &amp; <span style="color: #800000;">&quot; DESC&quot;</span><br />
<br />
&nbsp; &nbsp; &nbsp; <span style="color: #008000;">'Lance la requête et concatène les lignes<br />
</span> &nbsp; &nbsp; &nbsp;<span style="color: #151B8D; font-weight: bold;">Set</span> oDb = CurrentDb<br />
&nbsp; &nbsp; &nbsp; <span style="color: #151B8D; font-weight: bold;">Set</span> oRs = oDb.OpenRecordset(sSQL, dbOpenSnapshot)<br />
&nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">If</span> <span style="color: #8D38C9; font-weight: bold;">Not</span> oRs.EOF <span style="color: #8D38C9; font-weight: bold;">Then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">Do</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ConcatColonne = ConcatColonne &amp; oRs(0)<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; oRs.MoveNext<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">Loop</span> <span style="color: #8D38C9; font-weight: bold;">Until</span> oRs.EOF<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ConcatColonne = Left$(ConcatColonne, Len(ConcatColonne) - Len(Separateur))<br />
&nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">If</span><br />
&nbsp; &nbsp; &nbsp; oRs.<span style="color: #8D38C9; font-weight: bold;">Close</span><br />
&nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">If</span><br />
Finally:<br />
&nbsp; &nbsp;<span style="color: #151B8D; font-weight: bold;">Set</span> oRs = <span style="color: #00C2FF; font-weight: bold;">Nothing</span><br />
&nbsp; &nbsp;<span style="color: #151B8D; font-weight: bold;">Set</span> oDb = <span style="color: #00C2FF; font-weight: bold;">Nothing</span><br />
&nbsp; &nbsp;<span style="color: #E56717; font-weight: bold;">Exit</span> <span style="color: #E56717; font-weight: bold;">Function</span><br />
Catch:<br />
&nbsp; &nbsp;ConcatColonne = <span style="color: #800000;">&quot;Erreur !&quot;</span><br />
&nbsp; &nbsp;<span style="color: #151B8D; font-weight: bold;">Resume</span> Finally<br />
<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #E56717; font-weight: bold;">Function</span></div></div>
<p>&nbsp;<br />
<strong>Exemples d&rsquo;utilisation</strong><br />
Un collectionneur de modèles réduits, a noté consciencieusement ses achats de lots de voitures sur une feuille quadrillée. Un ami, utilisateur débutant d&rsquo;Access, a porté ce document dans une table Access sans connaître les formes normales de Codd !</p>
<p>Voici le code pour créér et peupler partiellement la table dont la structure n&rsquo;est pas à suivre&#8230;</p>
<div class="codecolorer-container vb blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="vb codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #E56717; font-weight: bold;">Public</span> <span style="color: #E56717; font-weight: bold;">Function</span> CreationTableConcat()<br />
&nbsp; &nbsp;Const cInsert <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span> = <span style="color: #800000;">&quot;INSERT INTO tConcat (Marque, Modele, DateAchat, Couleur, Nombre, Prix) VALUES &quot;</span><br />
<br />
&nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">With</span> DoCmd<br />
&nbsp; &nbsp; &nbsp; .SetWarnings <span style="color: #00C2FF; font-weight: bold;">False</span><br />
<br />
&nbsp; &nbsp; &nbsp; .RunSQL <span style="color: #800000;">&quot;CREATE TABLE tConcat (Marque VARCHAR, Modele VARCHAR, DateAchat DATE, Couleur VARCHAR, Nombre LONG, Prix DOUBLE);&quot;</span><br />
&nbsp; &nbsp; &nbsp; .RunSQL <span style="color: #800000;">&quot;CREATE INDEX IdxMarque ON tConcat (Marque);&quot;</span><br />
<br />
&nbsp; &nbsp; &nbsp; .RunSQL cInsert &amp; <span style="color: #800000;">&quot;('Citroën','DS',#6/3/1993#,'blanc',2,85.25);&quot;</span><br />
&nbsp; &nbsp; &nbsp; .RunSQL cInsert &amp; <span style="color: #800000;">&quot;('Citroën','DS',#2/13/1999#,'blanc',5,405.3);&quot;</span><br />
&nbsp; &nbsp; &nbsp; .RunSQL cInsert &amp; <span style="color: #800000;">&quot;('Peugeot','205',#11/18/1998#,'vert',1,31.2);&quot;</span><br />
&nbsp; &nbsp; &nbsp; .RunSQL cInsert &amp; <span style="color: #800000;">&quot;('Peugeot','404',#03/25/1978#,'noir',3,NULL);&quot;</span><br />
&nbsp; &nbsp; &nbsp; .RunSQL cInsert &amp; <span style="color: #800000;">&quot;('Peugeot','205',#12/07/1997#,'bleu',1,31.2);&quot;</span><br />
&nbsp; &nbsp; &nbsp; .RunSQL cInsert &amp; <span style="color: #800000;">&quot;('Peugeot','404',#03/25/1978#,'marron',1,42.1);&quot;</span><br />
&nbsp; &nbsp; &nbsp; .RunSQL cInsert &amp; <span style="color: #800000;">&quot;('Renault','R5',#01/28/1982#,'rouge',5,255.5);&quot;</span><br />
&nbsp; &nbsp; &nbsp; .RunSQL cInsert &amp; <span style="color: #800000;">&quot;('Renault','R4',#07/11/1991#,'bleu',3,159.9);&quot;</span><br />
&nbsp; &nbsp; &nbsp; .RunSQL cInsert &amp; <span style="color: #800000;">&quot;('Renault','R4',#07/11/1991#,'rouge',5,238.75);&quot;</span><br />
<br />
&nbsp; &nbsp; &nbsp; .SetWarnings <span style="color: #00C2FF; font-weight: bold;">True</span><br />
&nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">With</span><br />
<br />
&nbsp; &nbsp;MsgBox <span style="color: #800000;">&quot;Création terminée&quot;</span><br />
<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #E56717; font-weight: bold;">Function</span></div></div>
<p>Cette table contient 6 colonnes (Marque, Modèle, DateAchat, Couleur des voitures, Nombre de voiture du lot, Prix du lot).<br />
Chaque ligne de la table correspond à l&rsquo;achat d&rsquo;un lot de voitures et toutes les voitures d&rsquo;un lot ont la même couleur.</p>
<p>Le collectionneur souhaite obtenir des infos sur sa collection en concaténant l&rsquo;information dans une colonne car c&rsquo;est plus simple à lire&#8230;</p>
<p><strong>Quels sont les modèles achetés de la marque Peugeot ?</strong><br />
Comme la colonne pivot &lsquo;Marque&rsquo; doit être égale à &lsquo;Peugeot&rsquo;, on peut écrire la simple requête suivante :</p>
<div class="codecolorer-container sql blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #ff0000;">&quot;Peugeot&quot;</span> <span style="color: #993333; font-weight: bold;">AS</span> Marque<span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;ConcatColonne<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;peugeot&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">&quot;marque&quot;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #ff0000;">&quot;modele&quot;</span><span style="color: #66cc66;">,</span> &nbsp;<span style="color: #ff0000;">&quot;tConcat&quot;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #ff0000;">&quot;&quot;</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">0</span><span style="color: #66cc66;">,</span><span style="color: #993333; font-weight: bold;">FALSE</span><span style="color: #66cc66;">,</span><span style="color: #993333; font-weight: bold;">TRUE</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">&quot;,&quot;</span><span style="color: #66cc66;">&#41;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #66cc66;">&#91;</span><span style="color: #993333; font-weight: bold;">MOD</span>èles<span style="color: #66cc66;">&#93;</span></div></div>
<p>La valeur pivot est &lsquo;Peugeot&rsquo;, la colonne pivot (ou de regroupement) est &lsquo;Marque&rsquo;, la colonne à concaténer est &lsquo;Modele&rsquo;, la table est &lsquo;tConcat&rsquo;, la clause Where est vide &laquo;&nbsp;&nbsp;&raquo;, pas de regroupement des lots ayant le même modèle d&rsquo;où la valeur 0, on retourne les modèles dont le nom est vide ou NULL (False), on souhaite trier par ordre Ascendant les modèles concaténés (True), et le séparateur entre les modèles est une virgule &lsquo;,&rsquo;.<br />
<br />
On obtient donc :</p>
<div class="codecolorer-container text geshi" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Marque &nbsp;| Modèles &nbsp; <br />
Peugeot | 205,205,404,404</div></div>
<p>
Le collectionneur est satisfait mais il préfère regrouper les modèles communs et ajouter un espace après la &lsquo;,&rsquo;<br />
La requête devient :</p>
<div class="codecolorer-container sql blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #ff0000;">&quot;Peugeot&quot;</span> <span style="color: #993333; font-weight: bold;">AS</span> Marque<span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;ConcatColonne<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;peugeot&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">&quot;marque&quot;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #ff0000;">&quot;modele&quot;</span><span style="color: #66cc66;">,</span> &nbsp;<span style="color: #ff0000;">&quot;tConcat&quot;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #ff0000;">&quot;&quot;</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,</span><span style="color: #993333; font-weight: bold;">FALSE</span><span style="color: #66cc66;">,</span><span style="color: #993333; font-weight: bold;">TRUE</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">&quot;, &quot;</span><span style="color: #66cc66;">&#41;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #66cc66;">&#91;</span><span style="color: #993333; font-weight: bold;">MOD</span>èles<span style="color: #66cc66;">&#93;</span></div></div>
<p>Pour regrouper les modèles, il suffit de passer à <strong>1</strong> au lieu de <strong>0</strong> le paramètre &lsquo;RegrouperCompter&rsquo;. De plus, le séparateur devient &lsquo;, &lsquo; au lieu de &lsquo;,&rsquo;.<br />
<br />
On obtient alors :</p>
<div class="codecolorer-container text geshi" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Marque &nbsp;| Modèles &nbsp; <br />
Peugeot | 205, 404</div></div>
<p>
Il est satisfait mais il perd une information importante qui est le nombre de lots achetés et finalement il se demande si le séparateur &lsquo; / &lsquo; ne serait pas mieux&#8230;<br />
La solution devient :</p>
<div class="codecolorer-container sql blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #ff0000;">&quot;Peugeot&quot;</span> <span style="color: #993333; font-weight: bold;">AS</span> Marque<span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;ConcatColonne<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;peugeot&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">&quot;marque&quot;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #ff0000;">&quot;modele&quot;</span><span style="color: #66cc66;">,</span> &nbsp;<span style="color: #ff0000;">&quot;tConcat&quot;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #ff0000;">&quot;&quot;</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">,</span><span style="color: #993333; font-weight: bold;">FALSE</span><span style="color: #66cc66;">,</span><span style="color: #993333; font-weight: bold;">TRUE</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">&quot; / &quot;</span><span style="color: #66cc66;">&#41;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #66cc66;">&#91;</span><span style="color: #993333; font-weight: bold;">MOD</span>èles<span style="color: #66cc66;">&#93;</span></div></div>
<p>Pour afficher le compte par modèle, on passe la valeur du paramètre &lsquo;RegrouperCompter&rsquo; à <strong>2</strong>, et le séparateur est modifié.<br />
<br />
Résultat :</p>
<div class="codecolorer-container text geshi" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Marque &nbsp;| Modèles &nbsp; <br />
Peugeot | 205 (2) / 404 (2)</div></div>
<p>&nbsp;<br />
<strong>Qu&rsquo;elles sont les dates d&rsquo;achat de ces lots du plus récent au plus ancien ?</strong></p>
<div class="codecolorer-container sql blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #ff0000;">&quot;Peugeot&quot;</span> <span style="color: #993333; font-weight: bold;">AS</span> Marque<span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;ConcatColonne<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;peugeot&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">&quot;marque&quot;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #ff0000;">&quot;dateachat&quot;</span><span style="color: #66cc66;">,</span> &nbsp;<span style="color: #ff0000;">&quot;tConcat&quot;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #ff0000;">&quot;&quot;</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">,</span><span style="color: #993333; font-weight: bold;">FALSE</span><span style="color: #66cc66;">,</span><span style="color: #993333; font-weight: bold;">FALSE</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">&quot; ; &quot;</span><span style="color: #66cc66;">&#41;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #66cc66;">&#91;</span>Dates achat<span style="color: #66cc66;">&#93;</span></div></div>
<p>La colonne à concaténer devient &lsquo;DateAchat&rsquo; et le paramètre &lsquo;TriAscendant&rsquo; devient &lsquo;False&rsquo;.<br />
<br />
Résultat :</p>
<div class="codecolorer-container text geshi" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Marque &nbsp;| Dates achat<br />
Peugeot | 18/11/1998 (1) ; 07/12/1997 (1) ; 25/03/1978 (2)</div></div>
<p>&nbsp;<br />
<strong>Quels sont les prix d&rsquo;achat de ces lots ?</strong></p>
<div class="codecolorer-container sql blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #ff0000;">&quot;Peugeot&quot;</span> <span style="color: #993333; font-weight: bold;">AS</span> Marque<span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;ConcatColonne<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;peugeot&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">&quot;marque&quot;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #ff0000;">&quot;prix&quot;</span> &nbsp; <span style="color: #66cc66;">,</span> <span style="color: #ff0000;">&quot;tConcat&quot;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #ff0000;">&quot;&quot;</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">,</span><span style="color: #993333; font-weight: bold;">FALSE</span><span style="color: #66cc66;">,</span><span style="color: #993333; font-weight: bold;">FALSE</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">&quot; ; &quot;</span><span style="color: #66cc66;">&#41;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #66cc66;">&#91;</span>Prix<span style="color: #66cc66;">&#93;</span></div></div>
<p>
On obtient :</p>
<div class="codecolorer-container text geshi" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Marque &nbsp;| Prix<br />
Peugeot | 42,1 (1) ; 31,2 (2) ; &nbsp;(1)</div></div>
<p>On remarque que le dernier compte (1) est sans valeur. En effet, un prix n&rsquo;était pas renseigné dans le document&#8230;<br />
Le collectionneur me dit alors : &lsquo;Cachez-moi cette erreur que je ne saurais voir&#8230;&rsquo;<br />
<br />
La requête devient donc :</p>
<div class="codecolorer-container sql blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #ff0000;">&quot;Peugeot&quot;</span> <span style="color: #993333; font-weight: bold;">AS</span> Marque<span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;ConcatColonne<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;peugeot&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">&quot;marque&quot;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #ff0000;">&quot;prix&quot;</span> &nbsp; <span style="color: #66cc66;">,</span> <span style="color: #ff0000;">&quot;tConcat&quot;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #ff0000;">&quot;&quot;</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">,</span><span style="color: #993333; font-weight: bold;">TRUE</span><span style="color: #66cc66;">,</span><span style="color: #993333; font-weight: bold;">FALSE</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">&quot; ; &quot;</span><span style="color: #66cc66;">&#41;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #66cc66;">&#91;</span>Prix<span style="color: #66cc66;">&#93;</span></div></div>
<p>Il suffit de mettre à &lsquo;True&rsquo; le paramètre &lsquo;PasVideNULL&rsquo;.<br />
<br />
On obtient finalement :</p>
<div class="codecolorer-container text geshi" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Marque &nbsp;| Prix<br />
Peugeot | 42,1 (1) ; 31,2 (2)</div></div>
<p>&nbsp;<br />
<strong>Quels sont les prix d&rsquo;achat, toutes marques confondues ?</strong><br />
Il est normalement nécessaire de renseigner la valeur et la colonne du pivot&#8230;<br />
La solution consiste à mettre 0 pour &lsquo;ValeurColonnePivot&rsquo; et &lsquo;0&rsquo; pour &lsquo;NomColonnePivot&rsquo;<br />
La requête devient :</p>
<div class="codecolorer-container sql blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #ff0000;">&quot;Toutes&quot;</span> <span style="color: #993333; font-weight: bold;">AS</span> Marque<span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;ConcatColonne<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">&quot;0&quot;</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">&quot;prix&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">&quot;tConcat&quot;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #ff0000;">&quot;&quot;</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">,</span><span style="color: #993333; font-weight: bold;">TRUE</span><span style="color: #66cc66;">,</span><span style="color: #993333; font-weight: bold;">FALSE</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">&quot; ; &quot;</span><span style="color: #66cc66;">&#41;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #66cc66;">&#91;</span>Prix<span style="color: #66cc66;">&#93;</span></div></div>
<p>et le résultat :</p>
<div class="codecolorer-container text geshi" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Marque &nbsp;| Prix<br />
Toutes &nbsp;| 405,3 (1) ; 255,5 (1) ; 238,75 (1) ; 159,9 (1) ; 85,25 (1) ; 42,1 (1) ; 31,2 (2)</div></div>
<p>
Ca serait possible d&rsquo;avoir tous les prix unitaires ?<br />
Requête :</p>
<div class="codecolorer-container sql blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #ff0000;">&quot;Toutes&quot;</span> <span style="color: #993333; font-weight: bold;">AS</span> Marque<span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;ConcatColonne<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">&quot;0&quot;</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">&quot;[prix]/[nombre]&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">&quot;tConcat&quot;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #ff0000;">&quot;&quot;</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">,</span><span style="color: #993333; font-weight: bold;">TRUE</span><span style="color: #66cc66;">,</span><span style="color: #993333; font-weight: bold;">FALSE</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">&quot; - &quot;</span><span style="color: #66cc66;">&#41;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #66cc66;">&#91;</span>Prix<span style="color: #66cc66;">&#93;</span></div></div>
<p>On déclare que la colonne concaténée est la division du prix sur le nombre de voiture du lot.<br />
Résultat :</p>
<div class="codecolorer-container text geshi" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Marque &nbsp;| Prix<br />
Toutes &nbsp;| 81,06 - 53,3 - 51,1 - 47,75 - 42,625 - 42,1 - 31,2</div></div>
<p>&nbsp;<br />
<strong>Quels sont les modèles de chaque marque ?</strong><br />
Cette fois-ci, il faut utiliser la <strong>clause FROM </strong> de la requête pour passer en revue l&rsquo;ensemble des marques :</p>
<div class="codecolorer-container sql blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">SELECT</span> &nbsp; Marque<span style="color: #66cc66;">,</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ConcatColonne<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#91;</span>marque<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">&quot;marque&quot;</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">&quot;modele&quot;</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">&quot;tConcat&quot;</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">&quot;&quot;</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,</span><span style="color: #993333; font-weight: bold;">TRUE</span><span style="color: #66cc66;">,</span><span style="color: #993333; font-weight: bold;">TRUE</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">&quot; - &quot;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #66cc66;">&#91;</span><span style="color: #993333; font-weight: bold;">MOD</span>èles par marque<span style="color: #66cc66;">&#93;</span> <br />
<span style="color: #993333; font-weight: bold;">FROM</span> &nbsp; &nbsp; tconcat <br />
<span style="color: #993333; font-weight: bold;">GROUP</span> <span style="color: #993333; font-weight: bold;">BY</span> marque <br />
<span style="color: #993333; font-weight: bold;">ORDER</span> <span style="color: #993333; font-weight: bold;">BY</span> marque</div></div>
<p>Résultat :</p>
<div class="codecolorer-container text geshi" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Marque &nbsp;| Modèles par marque<br />
Citroën | DS<br />
Peugeot | 205 - 404<br />
Renault | R4 - R5</div></div>
<p>&nbsp;<br />
<strong>Quels sont les marques et modèles pour chaque couleur ?</strong></p>
<div class="codecolorer-container sql blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">SELECT</span> &nbsp; Couleur<span style="color: #66cc66;">,</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ConcatColonne<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#91;</span>couleur<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">&quot;couleur&quot;</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">&quot;marque &amp; &quot;</span><span style="color: #ff0000;">&quot; &quot;</span><span style="color: #ff0000;">&quot; &amp; modele&quot;</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">&quot;tConcat&quot;</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">&quot;&quot;</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,</span><span style="color: #993333; font-weight: bold;">FALSE</span><span style="color: #66cc66;">,</span><span style="color: #993333; font-weight: bold;">TRUE</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">&quot; - &quot;</span><span style="color: #66cc66;">&#41;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #66cc66;">&#91;</span>Marque et <span style="color: #993333; font-weight: bold;">MOD</span>èle<span style="color: #66cc66;">&#93;</span> <br />
<span style="color: #993333; font-weight: bold;">FROM</span> &nbsp; &nbsp; tconcat <br />
<span style="color: #993333; font-weight: bold;">GROUP</span> <span style="color: #993333; font-weight: bold;">BY</span> Couleur <br />
<span style="color: #993333; font-weight: bold;">ORDER</span> <span style="color: #993333; font-weight: bold;">BY</span> Couleur</div></div>
<p>Résultat :</p>
<div class="codecolorer-container text geshi" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Couleur | Marque et modèle<br />
blanc &nbsp; | Citroën DS<br />
bleu &nbsp; &nbsp;| Peugeot 205 - Renault R4<br />
marron &nbsp;| Peugeot 404<br />
noir &nbsp; &nbsp;| Peugeot 404<br />
rouge &nbsp; | Renault R4 - Renault R5<br />
vert &nbsp; &nbsp;| Peugeot 205</div></div>
<p>
Puis-je avoir une présentation inversée ?</p>
<div class="codecolorer-container sql blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">SELECT</span> &nbsp; <span style="color: #66cc66;">&#91;</span>Marque<span style="color: #66cc66;">&#93;</span> &amp; <span style="color: #ff0000;">&quot; &quot;</span> &amp; <span style="color: #66cc66;">&#91;</span>modele<span style="color: #66cc66;">&#93;</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #66cc66;">&#91;</span>Marque et <span style="color: #993333; font-weight: bold;">MOD</span>èle<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">,</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ConcatColonne<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#91;</span>marque<span style="color: #66cc66;">&#93;</span> &amp; <span style="color: #ff0000;">&quot; &quot;</span> &amp; <span style="color: #66cc66;">&#91;</span>Modele<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">&quot;[Marque] &amp; &quot;</span><span style="color: #ff0000;">&quot; &quot;</span><span style="color: #ff0000;">&quot; &amp; [modele]&quot;</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">&quot;couleur&quot;</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">&quot;tConcat&quot;</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">&quot;&quot;</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,</span><span style="color: #993333; font-weight: bold;">FALSE</span><span style="color: #66cc66;">,</span><span style="color: #993333; font-weight: bold;">TRUE</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">&quot; - &quot;</span><span style="color: #66cc66;">&#41;</span> &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #66cc66;">&#91;</span>Couleur<span style="color: #66cc66;">&#93;</span> <br />
<span style="color: #993333; font-weight: bold;">FROM</span> &nbsp; &nbsp; tconcat <br />
<span style="color: #993333; font-weight: bold;">GROUP</span> <span style="color: #993333; font-weight: bold;">BY</span> <span style="color: #66cc66;">&#91;</span>Marque<span style="color: #66cc66;">&#93;</span> &amp; <span style="color: #ff0000;">&quot; &quot;</span> &amp; <span style="color: #66cc66;">&#91;</span>modele<span style="color: #66cc66;">&#93;</span> <br />
<span style="color: #993333; font-weight: bold;">ORDER</span> <span style="color: #993333; font-weight: bold;">BY</span> <span style="color: #66cc66;">&#91;</span>Marque<span style="color: #66cc66;">&#93;</span> &amp; <span style="color: #ff0000;">&quot; &quot;</span> &amp; <span style="color: #66cc66;">&#91;</span>modele<span style="color: #66cc66;">&#93;</span></div></div>
<p>qui donne :</p>
<div class="codecolorer-container text geshi" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Marque et modèle | Couleur<br />
Citroën DS &nbsp; &nbsp; &nbsp; | blanc<br />
Peugeot 205 &nbsp; &nbsp; &nbsp;| bleu - vert<br />
Peugeot 404 &nbsp; &nbsp; &nbsp;| marron - noir<br />
Renault R4 &nbsp; &nbsp; &nbsp; | bleu - rouge<br />
Renault R5 &nbsp; &nbsp; &nbsp; | rouge</div></div>
<p>Enfin, je souhaite afficher séparément les colonnes &lsquo;Marque&rsquo; et &lsquo;Modèle&rsquo; et ne pas voir les informations pour &lsquo;Citroën&rsquo;<br />
La requête :</p>
<div class="codecolorer-container sql blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">SELECT</span> &nbsp; Marque<span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Modele<span style="color: #66cc66;">,</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ConcatColonne<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#91;</span>Marque<span style="color: #66cc66;">&#93;</span> &amp; <span style="color: #ff0000;">&quot; &quot;</span> &amp; <span style="color: #66cc66;">&#91;</span>Modele<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #ff0000;">&quot;[Marque] &amp; &quot;</span><span style="color: #ff0000;">&quot; &quot;</span><span style="color: #ff0000;">&quot; &amp; [modele]&quot;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #ff0000;">&quot;couleur&quot;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #ff0000;">&quot;tConcat&quot;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #ff0000;">&quot;Marque &lt;&gt; 'citroën'&quot;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">FALSE</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">TRUE</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #ff0000;">&quot; - &quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">&#41;</span> &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #66cc66;">&#91;</span>Couleur<span style="color: #66cc66;">&#93;</span> <br />
<span style="color: #993333; font-weight: bold;">FROM</span> &nbsp; &nbsp; tconcat <br />
<span style="color: #993333; font-weight: bold;">GROUP</span> <span style="color: #993333; font-weight: bold;">BY</span> Marque<span style="color: #66cc66;">,</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Modele<br />
<span style="color: #993333; font-weight: bold;">HAVING</span> &nbsp; Marque <span style="color: #66cc66;">&lt;&gt;</span> <span style="color: #ff0000;">'Citroën'</span><br />
<span style="color: #993333; font-weight: bold;">ORDER</span> <span style="color: #993333; font-weight: bold;">BY</span> Marque<span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Modele</div></div>
<p>On remarquera l&rsquo;utilisation du paramètre &lsquo;Filtre&rsquo; de la fonction ConcatColonne pour écarter la marque &lsquo;Citroën&rsquo; de la concaténation. Dans ce cas précis, l&rsquo;utilisation du filtre n&rsquo;est pas indispensable puisque la requête écarte elle-même cette marque (voir clause HAVING).<br />
Résultat attendu :</p>
<div class="codecolorer-container text geshi" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Marque &nbsp;| Modele | Couleur<br />
Peugeot | 205 &nbsp; &nbsp;| bleu - vert<br />
Peugeot | 404 &nbsp; &nbsp;| marron - noir<br />
Renault | R4 &nbsp; &nbsp; | bleu - rouge<br />
Renault | R5 &nbsp; &nbsp; | rouge</div></div>
<p>&nbsp;<br />
<strong>Performance</strong><br />
La fonction (et la requête sous-jacente!) est exécutée pour chaque ligne de la table ce qui ralentit sensiblement la requête principale.<br />
Il faudra donc limiter son usage à une table ou requête peu peuplée (&lt; 10 000 lignes ?) et si possible, indexer avec doublons la colonne pivot.<br />
De plus, pour ne pas dégrader les performances, éviter de réaliser des opérations complémentaires sur la colonne concaténée (Where, Order by, Group by) dans la requête principale.</p>
<p><strong>Lien</strong><br />
Voir ce <a href="http://blog.developpez.com/philben/p11140/ms-access-vba/transposer_une_colonne_en_lignes" title="Transposer une colonne en lignes">billet</a> pour réaliser une transposition inverse.</p>
<p>@+</p>
<p>Philippe</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Substituer des sous-chaînes</title>
		<link>https://blog.developpez.com/philben/p11230/vba-access/substituer_des_sous_chaines</link>
		<comments>https://blog.developpez.com/philben/p11230/vba-access/substituer_des_sous_chaines#comments</comments>
		<pubDate>Sat, 18 Aug 2012 01:56:07 +0000</pubDate>
		<dc:creator><![CDATA[philben]]></dc:creator>
				<category><![CDATA[SQL - Ms Access]]></category>
		<category><![CDATA[VBA - Ms Access]]></category>
		<category><![CDATA[Chaîne de caractères]]></category>
		<category><![CDATA[Code VBA]]></category>
		<category><![CDATA[Requête SQL]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Je vous présente une fonction polyvalente écrite en VBA qui permet de remplacer une ou plusieurs sous-chaînes en tenant compte ou non de la casse des caractères. La fonction Public Function Substituer(ByVal Chaine As String, ParamArray Substitutions() As Variant) As &#8230; <a href="https://blog.developpez.com/philben/p11230/vba-access/substituer_des_sous_chaines">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Je vous présente une fonction polyvalente écrite en VBA qui permet de remplacer une ou plusieurs sous-chaînes en tenant compte ou non de la casse des caractères.<br />
<span id="more-17"></span><br />
<strong>La fonction</strong></p>
<div class="codecolorer-container vb blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:400px;"><div class="vb codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #E56717; font-weight: bold;">Public</span> <span style="color: #E56717; font-weight: bold;">Function</span> Substituer(<span style="color: #151B8D; font-weight: bold;">ByVal</span> Chaine <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span>, <span style="color: #151B8D; font-weight: bold;">ParamArray</span> Substitutions() <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Variant</span>) <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span> <br />
<span style="color: #008000;">'Remplacer une ou plusieurs sous-chaines <br />
</span><span style="color: #008000;">'Philben - v1.0 - free to use <br />
</span> &nbsp; <span style="color: #151B8D; font-weight: bold;">Dim</span> i <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Long</span>, a <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Long</span>, b <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Long</span> <br />
&nbsp; &nbsp;<span style="color: #151B8D; font-weight: bold;">Dim</span> f <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span>, r <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span> <br />
&nbsp; &nbsp;<span style="color: #151B8D; font-weight: bold;">Dim</span> TypeComparaison <span style="color: #151B8D; font-weight: bold;">As</span> VbCompareMethod &nbsp; <span style="color: #008000;">'0 = vbBinaryCompare par défaut <br />
</span> <br />
&nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">If</span> Len(Chaine) &gt; 0 <span style="color: #8D38C9; font-weight: bold;">Then</span> <br />
&nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">For</span> i = 0 <span style="color: #8D38C9; font-weight: bold;">To</span> <span style="color: #151B8D; font-weight: bold;">UBound</span>(Substitutions) <span style="color: #8D38C9; font-weight: bold;">Step</span> 2 <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">If</span> VarType(Substitutions(i)) = vbString <span style="color: #8D38C9; font-weight: bold;">Then</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; f = Substitutions(i) <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; r = Substitutions(i + 1) <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">'si la longueur de la sous-chaine recherchée est &gt; à la chaine de remplacement =&gt; boucle de substitution <br />
</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">If</span> Len(f) &gt; Len(r) <span style="color: #8D38C9; font-weight: bold;">Then</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;a = Len(Chaine) <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">Do</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; b = a <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">If</span> InStr(1, Chaine, f, TypeComparaison) &gt; 0 <span style="color: #8D38C9; font-weight: bold;">Then</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Chaine = Replace(Chaine, f, r, , , TypeComparaison) <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;a = Len(Chaine) <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">If</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">Loop</span> <span style="color: #8D38C9; font-weight: bold;">Until</span> a = b <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #008000;">'sinon, substitution unique <br />
</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">ElseIf</span> InStr(1, Chaine, f, TypeComparaison) &gt; 0 <span style="color: #8D38C9; font-weight: bold;">Then</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Chaine = Replace(Chaine, f, r, , , TypeComparaison) <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">If</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">Else</span> &nbsp; <span style="color: #008000;">'nouveau type de comparaison <br />
</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;TypeComparaison = IIf(Substitutions(i) &lt;&gt; 0, vbTextCompare, vbBinaryCompare) <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; i = i - 1 &nbsp; <span style="color: #008000;">'Ajustement car step 2 de la boucle <br />
</span> &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">If</span> <br />
&nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">Next</span> i <br />
&nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">If</span> <br />
&nbsp;<br />
&nbsp; &nbsp;Substituer = Chaine <br />
<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #E56717; font-weight: bold;">Function</span></div></div>
<p><strong>Exemple d&rsquo;utilisation</strong><br />
Recopier la ligne suivante dans la fenêtre &lsquo;Exécution&rsquo; de l&rsquo;éditeur Visual Basic (F11) puis appuyer sur &lsquo;Entrée&rsquo; pour l&rsquo;exécuter.</p>
<div class="codecolorer-container vb blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="vb codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">? Substituer(<span style="color: #800000;">&quot;MA_Chaîne_______A_Corrigé&quot;</span>,<span style="color: #800000;">&quot;_&quot;</span>,<span style="color: #800000;">&quot; &quot;</span>,<span style="color: #800000;">&quot; &nbsp;&quot;</span>,<span style="color: #800000;">&quot; &quot;</span>,<span style="color: #800000;">&quot; A &quot;</span>,<span style="color: #800000;">&quot; à &quot;</span>,<span style="color: #800000;">&quot;î&quot;</span>,<span style="color: #800000;">&quot;i&quot;</span>,<span style="color: #800000;">&quot;é&quot;</span>,<span style="color: #800000;">&quot;er&quot;</span>,<span style="color: #00C2FF; font-weight: bold;">true</span>,<span style="color: #800000;">&quot;ma&quot;</span>,<span style="color: #800000;">&quot;La&quot;</span>)<br />
'Résultat:La Chaine à Corriger</div></div>
<p><strong>Explications</strong><br />
Le premier paramètre de la fonction contient la chaine à modifier.<br />
Le deuxième paramètre est un peu particulier car il s&rsquo;agit d&rsquo;une suite de paramètres qui sera interprétée comme un tableau de variants. Ce tableau contient l&rsquo;ensemble des substitutions à réaliser (couple chaine recherchée/chaine de remplacement) et éventuellement un booléen qui indique le type de comparaison (binaire ou textuelle) pour les remplacements suivants.</p>
<p>Par défaut, la fonction effectue une comparaison binaire pour rechercher et remplacer les sous-chaines c&rsquo;est à dire qu&rsquo;elle est <strong>sensible</strong> à la casse des caractères.</p>
<p>Dans notre exemple, on va tout d&rsquo;abord substituer le caractère &lsquo;_&rsquo; par un espace (&lsquo;_&rsquo;,&rsquo; &lsquo;) puis réduire le nombre d&rsquo;espaces contigus en un (&lsquo;  &lsquo;,&rsquo; &lsquo;). A ce stade on obtient :</p>
<div class="codecolorer-container vb blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="vb codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">? Substituer(<span style="color: #800000;">&quot;MA_Chaîne_______A_Corrigé&quot;</span>,<span style="color: #800000;">&quot;_&quot;</span>,<span style="color: #800000;">&quot; &quot;</span>,<span style="color: #800000;">&quot; &nbsp;&quot;</span>,<span style="color: #800000;">&quot; &quot;</span>) <br />
'Résultat:MA Chaîne A Corrigé</div></div>
<p>Lorsque la chaine de remplacement est plus courte que la chaine recherchée, la fonction réalise une boucle de réduction. Par exemple, 5 espaces contigus seront réduits en un même si la chaine recherchée n&rsquo;est que de deux espaces.</p>
<p>L&rsquo;étape suivante (&lsquo; A &lsquo;,&rsquo; à &lsquo;) recherche la lettre A en majuscule entourée d&rsquo;espaces, on remplace ensuite le i accentué par son équivalent sans accent (&lsquo;î&rsquo;,&rsquo;i&rsquo;) puis le &lsquo;é&rsquo; par &lsquo;er&rsquo;.</p>
<p>L&rsquo;étape suivante (True ou tout chiffre différent de 0) indique à la fonction que l&rsquo;on souhaite réaliser maintenant des comparaisons textuelles (vbTextCompare) donc insensibles à la casse des caractères. L&rsquo;étape suivante (&lsquo;ma&rsquo;,&rsquo;La&rsquo;) remplacera donc le texte &lsquo;ma&rsquo; par &lsquo;la&rsquo; quel que soit la casse des caractères.</p>
<p>On pourrait ajouter d&rsquo;autres remplacements et revenir aussi à une comparaison binaire (False ou le chiffre 0).</p>
<p><strong>Remarque</strong><br />
Dans le cas d&rsquo;une réduction de chaine, on réalise une boucle qui ne s&rsquo;arrête que si la longueur de la chaine est inchangée (&#8230;Loop Until a = b) après la fonction Replace(). Cette méthode est moins efficace que :</p>
<div class="codecolorer-container vb blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="vb codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #8D38C9; font-weight: bold;">While</span> InStr(1, Chaine, f, TypeComparaison) &gt; 0 <br />
&nbsp; &nbsp; &nbsp; Chaine = Replace(Chaine, f, r, , , TypeComparaison) <br />
Wend</div></div>
<p>mais on risque d&rsquo;entrer dans une <strong>boucle infinie</strong> si on souhaite réduire par exemple &lsquo;oe&rsquo; en &lsquo;Œ&rsquo; avec une comparaison <strong>textuelle</strong>&#8230; En effet, cette ligature est interprétée comme équivalente à &lsquo;oe&rsquo; :</p>
<div class="codecolorer-container vb blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="vb codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">? InStr(1, <span style="color: #800000;">&quot;oe&quot;</span>, <span style="color: #800000;">&quot;Œ&quot;</span>, vbTextCompare)</div></div>
<p>Access retourne la valeur 1 bien que l&rsquo;on s&rsquo;attend à obtenir 0&#8230;</p>
<p><strong>Pour le fun !</strong><br />
Une autre solution pour réduire les espaces :</p>
<div class="codecolorer-container vb blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="vb codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #008000;">'---<br />
</span>Substituer(<span style="color: #800000;">&quot;a &nbsp; &nbsp; &nbsp;b&quot;</span>, <span style="color: #800000;">&quot; &quot;</span>, vbVerticalTab &amp; vbFormFeed, vbFormFeed &amp; vbVerticalTab, vbNullString, vbVerticalTab &amp; vbFormFeed, <span style="color: #800000;">&quot; &quot;</span>) <br />
'---</div></div>
<p>Ce type de méthode est parfois utilisé dans les requêtes SQL pour s&rsquo;affranchir d&rsquo;une fonction personnelle dans la requête :</p>
<div class="codecolorer-container sql blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #993333; font-weight: bold;">REPLACE</span><span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">REPLACE</span><span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">REPLACE</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#91;</span>Ma Colonne<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">&quot; &quot;</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">&quot; &quot;</span> &amp; Chr<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span> Chr<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span> &amp; <span style="color: #ff0000;">&quot; &quot;</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">&quot;&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span> Chr<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">&quot;&quot;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> TEST <span style="color: #993333; font-weight: bold;">FROM</span> <span style="color: #66cc66;">...</span></div></div>
<p>@+</p>
<p>Philippe</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Regroupement de périodes chevauchées</title>
		<link>https://blog.developpez.com/philben/p11285/sql-access/regroupement-de-periodes-chevauchees</link>
		<comments>https://blog.developpez.com/philben/p11285/sql-access/regroupement-de-periodes-chevauchees#comments</comments>
		<pubDate>Tue, 07 Aug 2012 22:33:16 +0000</pubDate>
		<dc:creator><![CDATA[philben]]></dc:creator>
				<category><![CDATA[SQL - Ms Access]]></category>
		<category><![CDATA[Date]]></category>
		<category><![CDATA[Requête SQL]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/philben/?p=141</guid>
		<description><![CDATA[Vous avez une table avec une date de début et de fin et vous souhaitez connaître la date mini et la date maxi des périodes qui se chevauchent. Création de la table et des lignes Public Function CreationTablePeriode() &#160; &#160;Const &#8230; <a href="https://blog.developpez.com/philben/p11285/sql-access/regroupement-de-periodes-chevauchees">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Vous avez une table avec une date de début et de fin et vous souhaitez connaître la date mini et la date maxi des périodes qui se chevauchent.<br />
<span id="more-141"></span><br />
<strong>Création de la table et des lignes</strong></p>
<div class="codecolorer-container vb blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="vb codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #E56717; font-weight: bold;">Public</span> <span style="color: #E56717; font-weight: bold;">Function</span> CreationTablePeriode() <br />
&nbsp; &nbsp;Const cInsert <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span> = <span style="color: #800000;">&quot;INSERT INTO tPeriode (DateDebut, DateFin) VALUES &quot;</span> <br />
&nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">With</span> DoCmd <br />
&nbsp; &nbsp; &nbsp; .SetWarnings <span style="color: #00C2FF; font-weight: bold;">False</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; .RunSQL <span style="color: #800000;">&quot;CREATE TABLE tPeriode (Id AUTOINCREMENT PRIMARY KEY, DateDebut DATE NOT NULL, DateFin DATE NOT NULL)&quot;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; .RunSQL cInsert &amp; <span style="color: #800000;">&quot;('2012-01-03', '2012-01-03');&quot;</span> <br />
&nbsp; &nbsp; &nbsp; .RunSQL cInsert &amp; <span style="color: #800000;">&quot;('2011-12-20', '2012-01-04');&quot;</span> <br />
&nbsp; &nbsp; &nbsp; .RunSQL cInsert &amp; <span style="color: #800000;">&quot;('2012-01-04', '2012-01-07');&quot;</span> <br />
&nbsp; &nbsp; &nbsp; .RunSQL cInsert &amp; <span style="color: #800000;">&quot;('2012-01-06', '2012-01-10');&quot;</span> <br />
&nbsp; &nbsp; &nbsp; .RunSQL cInsert &amp; <span style="color: #800000;">&quot;('2012-05-01', '2012-05-01');&quot;</span> <br />
&nbsp; &nbsp; &nbsp; .RunSQL cInsert &amp; <span style="color: #800000;">&quot;('2012-05-02', '2012-05-03');&quot;</span> <br />
&nbsp; &nbsp; &nbsp; .RunSQL cInsert &amp; <span style="color: #800000;">&quot;('2012-05-03', '2012-05-03');&quot;</span> <br />
&nbsp; &nbsp; &nbsp; .RunSQL cInsert &amp; <span style="color: #800000;">&quot;('2012-05-03', '2012-05-05');&quot;</span> <br />
&nbsp; &nbsp; &nbsp; .RunSQL cInsert &amp; <span style="color: #800000;">&quot;('2012-05-04', '2012-05-10');&quot;</span> <br />
&nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; .SetWarnings <span style="color: #00C2FF; font-weight: bold;">True</span> <br />
&nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">With</span> <br />
&nbsp; &nbsp;MsgBox <span style="color: #800000;">&quot;Création terminée&quot;</span> <br />
<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #E56717; font-weight: bold;">Function</span></div></div>
<p><strong>Résultat attendu du jeu de test</strong><br />
Nous remarquons que la période :</p>
<ul>
<li>de la 1ère ligne [<strong>03/01/2012</strong>-03/01/2012] est chevauchée par celle de la 2ème [20/12/2011-<strong>04/01/2012</strong>]</li>
<li>de la 3ème ligne [<strong>04/01/2012</strong>-07/01/2012] chevauche celle de la 2ème [20/12/2011-<strong>04/01/2012</strong>]</li>
<li>de la 4ème ligne [<strong>06/01/2012</strong>-10/01/2012] chevauche celle de la 3ème [04/01/2012-<strong>07/01/2012</strong>]
</li>
</ul>
<p>Après regroupement, l&rsquo;étendue de cette première période va du <strong>20/12/2011</strong> au <strong>10/01/2012</strong></p>
<p><strong>La ligne n°5</strong> (01/05/2012-01/05/2012) n&rsquo;est chevauchée par aucune autre période et les 4 dernières lignes donnent une période du 02/05/2012 au 10/05/2012.</p>
<p>Le résultat attendu est :</p>
<ul>
<li>20/12/2012 &#8211; 10/01/2012</li>
<li>01/05/2012 &#8211; 01/05/2012</li>
<li>02/05/2012 &#8211; 10/05/2012</li>
</ul>
<p><strong>La requête</strong><br />
Il existe plusieurs méthodes pour arriver au résultat mais voici la requête la plus performante sous MS Access (et cerise sur le gâteau, visible dans l&rsquo;éditeur de requête !) :</p>
<div class="codecolorer-container sql blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">SELECT</span> &nbsp; &nbsp; &nbsp;DateDebutAS <span style="color: #66cc66;">&#91;</span><span style="color: #993333; font-weight: bold;">DATE</span> Début<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">MIN</span><span style="color: #66cc66;">&#40;</span>DateFin<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #66cc66;">&#91;</span><span style="color: #993333; font-weight: bold;">DATE</span> Fin<span style="color: #66cc66;">&#93;</span><br />
<span style="color: #993333; font-weight: bold;">FROM</span> &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">SELECT</span> &nbsp;DateDebut<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">FROM</span> &nbsp; &nbsp;tPeriode <span style="color: #993333; font-weight: bold;">AS</span> T1<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">WHERE</span> &nbsp; t1<span style="color: #66cc66;">.</span>DateDebut <span style="color: #66cc66;">&lt;=</span> <span style="color: #993333; font-weight: bold;">ALL</span> <span style="color: #66cc66;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">SELECT</span> DateDebut<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">FROM</span> &nbsp; tPeriode T2<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">WHERE</span> &nbsp;T2<span style="color: #66cc66;">.</span>DateDebut <span style="color: #66cc66;">=</span> T1<span style="color: #66cc66;">.</span>DateDebut<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">GROUP</span> <span style="color: #993333; font-weight: bold;">BY</span> DateDebut<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> T1<span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">SELECT</span> &nbsp;DateFin<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">FROM</span> &nbsp; &nbsp;tPeriode <span style="color: #993333; font-weight: bold;">AS</span> T1<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">WHERE</span> &nbsp; t1<span style="color: #66cc66;">.</span>DateFin <span style="color: #66cc66;">&gt;=</span> <span style="color: #993333; font-weight: bold;">ALL</span> <span style="color: #66cc66;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">SELECT</span> DateFin<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">FROM</span> &nbsp; tPeriode T2<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">WHERE</span> &nbsp;T2<span style="color: #66cc66;">.</span>DateFin <span style="color: #66cc66;">&gt;=</span> T1<span style="color: #66cc66;">.</span>DateDebut<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">AND</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;T2<span style="color: #66cc66;">.</span>DateDebut <span style="color: #66cc66;">&lt;=</span> T1<span style="color: #66cc66;">.</span>DateFin<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">GROUP</span> <span style="color: #993333; font-weight: bold;">BY</span> DateFin<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> T2<br />
<span style="color: #993333; font-weight: bold;">WHERE</span> &nbsp; &nbsp; t1<span style="color: #66cc66;">.</span>DateDebut <span style="color: #66cc66;">&lt;=</span> t2<span style="color: #66cc66;">.</span>DateFin<br />
<span style="color: #993333; font-weight: bold;">GROUP</span> <span style="color: #993333; font-weight: bold;">BY</span> &nbsp;DateDebut;</div></div>
<p><strong>Explications</strong><br />
La première sous-requête de la clause FROM (SELECT DateDebut&#8230;) retourne la date minimale des périodes chevauchées. En effet, la clause WHERE de cette sous-requête ne conserve que les dates de début qui sont inférieures ou égales aux périodes qui les chevauchent éventuellement.<br />
<strong>Prenons par exemple</strong> la ligne n°1 (03/01/2012). Sa date de début est-elle &lt;= à la date de début de la  période qui la chevauche ? La réponse est non puisque la date de début de la période du 20/12/2011 au 04/01/2012 est inférieure. La date du 03/01/2012 est donc retirée et ainsi de suite pour chaque ligne de la table.<br />
Le &#039;Group By DateDebut&#039; permet, au cas où,  de regrouper les lignes qui ont une même date de début.</p>
<p><strong>La deuxième sous-requête</strong> de la clause FROM (SELECT DateFin &#8230;) applique le même principe mais pour la date de fin.</p>
<p>A ce niveau là, on a visiblement pas de lien entre la date de début et la date de fin des périodes regroupées&#8230; d&rsquo;autant plus que l&rsquo;on réalise une jointure croisée entre les dates pour que la requête soit visible dans l&rsquo;éditeur.</p>
<p><strong>Pour s&rsquo;en sortir</strong>, on retire dans un premier temps les lignes incohérentes qui ont une date de fin &lt; à la date de début (&#8230;WHERE  t1.DateDebut &lt;= t2.DateFin&#8230;)<br />
Et la finesse finale qui consiste à dire que la date de fin de chaque regroupement de périodes est celle qui est la plus petite puisque nous avons retiré dans la clause WHERE précédente les périodes incohérentes et que les périodes restantes ne peuvent se chevaucher.<br />
On ajoute un GROUP BY sur la date de début pour permettre l&#039;utilisation de la fonction MIN() sur la date de fin.</p>
<p><strong>Test de performance</strong><br />
Voici une petite fonction qui va générer 2000 lignes dans la table pour tester la performance de la requête</p>
<div class="codecolorer-container vb blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="vb codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #E56717; font-weight: bold;">Public</span> <span style="color: #E56717; font-weight: bold;">Function</span> TablePeriodeAddLines() <br />
&nbsp; &nbsp; <span style="color: #151B8D; font-weight: bold;">Dim</span> odb <span style="color: #151B8D; font-weight: bold;">As</span> DAO.Database <br />
&nbsp; &nbsp; <span style="color: #151B8D; font-weight: bold;">Dim</span> ors <span style="color: #151B8D; font-weight: bold;">As</span> DAO.Recordset <br />
&nbsp; &nbsp; <span style="color: #151B8D; font-weight: bold;">Dim</span> i <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Long</span> <br />
&nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; <span style="color: #151B8D; font-weight: bold;">Set</span> odb = CurrentDb <br />
&nbsp; &nbsp; <span style="color: #151B8D; font-weight: bold;">Set</span> ors = odb.OpenRecordset(<span style="color: #800000;">&quot;select * from tperiode&quot;</span>, dbOpenDynaset) <br />
&nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; Randomize <br />
&nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">With</span> ors <br />
&nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">For</span> i = 1 <span style="color: #8D38C9; font-weight: bold;">To</span> 2000 <br />
&nbsp; &nbsp; &nbsp; &nbsp; .AddNew <br />
&nbsp; &nbsp; &nbsp; &nbsp; !datedebut = DateAdd(<span style="color: #800000;">&quot;d&quot;</span>, Rnd() * 1000 - 500, <span style="color: #F660AB; font-weight: bold;">Date</span>) <br />
&nbsp; &nbsp; &nbsp; &nbsp; !datefin = !datedebut + Int(Rnd() * 5) <br />
&nbsp; &nbsp; &nbsp; &nbsp; .Update <br />
&nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">Next</span> i <br />
&nbsp; &nbsp; .<span style="color: #8D38C9; font-weight: bold;">Close</span> <br />
&nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">With</span> <br />
&nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; <span style="color: #151B8D; font-weight: bold;">Set</span> ors = <span style="color: #00C2FF; font-weight: bold;">Nothing</span> <br />
&nbsp; &nbsp; <span style="color: #151B8D; font-weight: bold;">Set</span> odb = <span style="color: #00C2FF; font-weight: bold;">Nothing</span> <br />
&nbsp; &nbsp; MsgBox <span style="color: #800000;">&quot;Ajout terminée&quot;</span> <br />
<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #E56717; font-weight: bold;">Function</span></div></div>
<p>@+</p>
<p>Philippe</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Transposer une colonne en lignes</title>
		<link>https://blog.developpez.com/philben/p11140/vba-access/transposer_une_colonne_en_lignes</link>
		<comments>https://blog.developpez.com/philben/p11140/vba-access/transposer_une_colonne_en_lignes#comments</comments>
		<pubDate>Sun, 08 Jul 2012 06:02:53 +0000</pubDate>
		<dc:creator><![CDATA[philben]]></dc:creator>
				<category><![CDATA[SQL - Ms Access]]></category>
		<category><![CDATA[VBA - Ms Access]]></category>
		<category><![CDATA[Chaîne de caractères]]></category>
		<category><![CDATA[Code VBA]]></category>
		<category><![CDATA[Requête SQL]]></category>
		<category><![CDATA[Transposer]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Après l&#8217;import d&#8217;un fichier Excel dans une table Access, on souhaitait regrouper et compter les sous-chaînes d&#8217;une colonne par une requête SQL. On part donc de : &#8230;pour arriver à : Générer la table et ses lignes Cette fontion génère &#8230; <a href="https://blog.developpez.com/philben/p11140/vba-access/transposer_une_colonne_en_lignes">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Après l&rsquo;import d&rsquo;un fichier Excel dans une table Access, on souhaitait regrouper et compter les sous-chaînes d&rsquo;une colonne par une requête SQL.</p>
<p>On part donc de :<br />
<img src="http://philben.developpez.com/TranspositionTable.png" alt="Colonne à transposer" /></p>
<p>&#8230;pour arriver à :<br />
<img src="http://philben.developpez.com/TranspositionResultat.png" alt="Transposition de la colonne en lignes" /><br />
<span id="more-29"></span><br />
<strong>Générer la table et ses lignes</strong><br />
Cette fontion génère la table tTransposition qui est peuplée de 10 000 lignes de textes aléatoires.<br />
Pour l&rsquo;utiliser, copier l&rsquo;ensemble du code dans un module VBA, placer le focus dans la fonction &lsquo;CreationTableTransposition()&rsquo; puis appuyer sur &lsquo;<strong>F5</strong>&lsquo; pour l&rsquo;exécuter.</p>
<div class="codecolorer-container vb blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:400px;"><div class="vb codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #E56717; font-weight: bold;">Public</span> <span style="color: #E56717; font-weight: bold;">Function</span> CreationTableTransposition() <br />
&nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">With</span> DoCmd <br />
&nbsp; &nbsp; &nbsp; .SetWarnings <span style="color: #00C2FF; font-weight: bold;">False</span> <br />
&nbsp; &nbsp; &nbsp; .RunSQL <span style="color: #800000;">&quot;CREATE TABLE tTransposition (Texte VARCHAR NOT NULL);&quot;</span> <br />
&nbsp; &nbsp; &nbsp; .SetWarnings <span style="color: #00C2FF; font-weight: bold;">True</span> <br />
&nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">With</span> <br />
&nbsp; &nbsp;GenereTranspositionTextes <br />
&nbsp;<br />
&nbsp; &nbsp;MsgBox <span style="color: #800000;">&quot;Création terminée&quot;</span> <br />
<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #E56717; font-weight: bold;">Function</span> <br />
&nbsp;<br />
<span style="color: #E56717; font-weight: bold;">Private</span> <span style="color: #E56717; font-weight: bold;">Function</span> GenereTranspositionTextes() <br />
&nbsp; &nbsp;Const clMaxLignes <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Long</span> = 10000 <br />
&nbsp;<br />
&nbsp; &nbsp;<span style="color: #151B8D; font-weight: bold;">Dim</span> odb <span style="color: #151B8D; font-weight: bold;">As</span> DAO.Database <br />
&nbsp; &nbsp;<span style="color: #151B8D; font-weight: bold;">Dim</span> ors <span style="color: #151B8D; font-weight: bold;">As</span> DAO.Recordset <br />
&nbsp; &nbsp;<span style="color: #151B8D; font-weight: bold;">Dim</span> Texte <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span> <br />
&nbsp; &nbsp;<span style="color: #151B8D; font-weight: bold;">Dim</span> i <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Long</span>, j <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Long</span>, n <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Long</span> <br />
&nbsp;<br />
&nbsp; &nbsp;<span style="color: #151B8D; font-weight: bold;">Set</span> odb = CurrentDb <br />
&nbsp; &nbsp;<span style="color: #151B8D; font-weight: bold;">Set</span> ors = odb.OpenRecordset(<span style="color: #800000;">&quot;tTransposition&quot;</span>, dbOpenDynaset) <br />
&nbsp; &nbsp;Randomize <br />
&nbsp;<br />
&nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">With</span> ors <br />
&nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">For</span> i = 1 <span style="color: #8D38C9; font-weight: bold;">To</span> clMaxLignes <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #008000;">'construction du texte <br />
</span> &nbsp; &nbsp; &nbsp; &nbsp; n = Int(Rnd() * 9) &nbsp; <span style="color: #008000;">'nombre de separateurs <br />
</span> &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">If</span> n &gt; 0 <span style="color: #8D38C9; font-weight: bold;">Then</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Texte = <span style="color: #800000;">&quot;&quot;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">For</span> j = 1 <span style="color: #8D38C9; font-weight: bold;">To</span> n <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Texte = Texte &amp; <span style="color: #F660AB; font-weight: bold;">String</span>$(j, 49 + j - 1) &amp; <span style="color: #800000;">&quot;@&quot;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">Next</span> j <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Texte = Left$(Texte, Len(Texte) - 1) <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">Else</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; j = Int(Rnd() * 9) + 1 <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Texte = <span style="color: #F660AB; font-weight: bold;">String</span>$(j, 49 + j - 1) <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">If</span> <br />
&nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #008000;">'Ajout de la ligne <br />
</span> &nbsp; &nbsp; &nbsp; &nbsp; .AddNew <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;!Texte = Texte <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.Update <br />
&nbsp;<br />
&nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">Next</span> i <br />
&nbsp; &nbsp; &nbsp; .<span style="color: #8D38C9; font-weight: bold;">Close</span> <br />
&nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">With</span> <br />
&nbsp;<br />
&nbsp; &nbsp;<span style="color: #151B8D; font-weight: bold;">Set</span> ors = <span style="color: #00C2FF; font-weight: bold;">Nothing</span> <br />
&nbsp; &nbsp;<span style="color: #151B8D; font-weight: bold;">Set</span> odb = <span style="color: #00C2FF; font-weight: bold;">Nothing</span> <br />
<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #E56717; font-weight: bold;">Function</span></div></div>
<p><strong>La trousse à outils VBA</strong><br />
Pour chaque ligne de la table, il faudra compter les occurrences du séparateur &laquo;&nbsp;@&nbsp;&raquo;, déterminer ainsi le nombre de sous-chaînes (nombre de séparateurs + 1) qui seront enfin séparées et extraites.</p>
<p>Par chance, on a déjà présenté dans ce blog deux fonctions personnelles qui remplissent ces tâches :</p>
<div class="codecolorer-container vb blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="vb codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #E56717; font-weight: bold;">Public</span> <span style="color: #E56717; font-weight: bold;">Function</span> CompteOccurrences(<span style="color: #151B8D; font-weight: bold;">ByVal</span> Texte <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span>, <span style="color: #151B8D; font-weight: bold;">ByVal</span> Chaine <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span>, <span style="color: #151B8D; font-weight: bold;">Optional</span> <span style="color: #151B8D; font-weight: bold;">ByVal</span> TypeComparaison <span style="color: #151B8D; font-weight: bold;">As</span> VbCompareMethod = vbBinaryCompare) <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Long</span> <br />
&nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">If</span> Texte &nbsp;vbNullString <span style="color: #8D38C9; font-weight: bold;">Then</span> CompteOccurrences = <span style="color: #151B8D; font-weight: bold;">UBound</span>(Split(Texte, Chaine, -1, TypeComparaison)) <br />
<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #E56717; font-weight: bold;">Function</span></div></div>
<p>et</p>
<div class="codecolorer-container vb blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:400px;"><div class="vb codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #E56717; font-weight: bold;">Public</span> <span style="color: #E56717; font-weight: bold;">Function</span> Token(<span style="color: #151B8D; font-weight: bold;">ByVal</span> Texte <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span>, <span style="color: #151B8D; font-weight: bold;">ByVal</span> Separateur <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span>, <span style="color: #151B8D; font-weight: bold;">ByVal</span> Numero <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Long</span>, <span style="color: #151B8D; font-weight: bold;">Optional</span> <span style="color: #151B8D; font-weight: bold;">ByVal</span> TypeComparaison <span style="color: #151B8D; font-weight: bold;">As</span> VbCompareMethod = vbBinaryCompare) <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span> <br />
<span style="color: #008000;">'Retourne le token spécifié par son numéro <br />
</span><span style="color: #008000;">'Auteur : Philben - v1.01 <br />
</span><span style="color: #008000;">'Exemple : Token(&quot;a-b-c&quot;,&quot;-&quot;,2) -&gt; b <br />
</span> &nbsp; <span style="color: #151B8D; font-weight: bold;">Dim</span> Tok <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span> <br />
&nbsp; &nbsp;<span style="color: #151B8D; font-weight: bold;">Dim</span> x <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Long</span>, y <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Long</span> <br />
&nbsp;<br />
&nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">Select</span> <span style="color: #8D38C9; font-weight: bold;">Case</span> Numero <br />
&nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">Case</span> <span style="color: #8D38C9; font-weight: bold;">Is</span> &gt; 1 <br />
&nbsp; &nbsp; &nbsp; x = InStr(1, Replace(Texte, Separateur, vbNullString, 1, Numero - 2, TypeComparaison), Separateur, TypeComparaison) <br />
&nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">If</span> x &gt; 0 <span style="color: #8D38C9; font-weight: bold;">Then</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;x = x + Len(Separateur) * (Numero - 1) <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;y = InStr(x, Texte, Separateur, TypeComparaison) <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">If</span> y &gt; 0 <span style="color: #8D38C9; font-weight: bold;">Then</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Tok = Mid$(Texte, x, y - x) <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">Else</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Tok = Mid$(Texte, x) <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">If</span> <br />
&nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">If</span> <br />
&nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">Case</span> 1 <br />
&nbsp; &nbsp; &nbsp; x = InStr(1, Texte, Separateur, TypeComparaison) <br />
&nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">If</span> x &gt; 0 <span style="color: #8D38C9; font-weight: bold;">Then</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Tok = Left$(Texte, x - 1) <br />
&nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">Else</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Tok = Texte <br />
&nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">If</span> <br />
&nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">Case</span> -1 <br />
&nbsp; &nbsp; &nbsp; x = InStrRev(Texte, Separateur, -1, TypeComparaison) <br />
&nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">If</span> x &gt; 0 <span style="color: #8D38C9; font-weight: bold;">Then</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Tok = Mid$(Texte, x + Len(Separateur)) <br />
&nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">Else</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Tok = Texte <br />
&nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">If</span> <br />
&nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">Select</span> <br />
&nbsp; &nbsp;Token = Tok <br />
<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #E56717; font-weight: bold;">Function</span></div></div>
<p><strong>Comment créer des lignes qui n&rsquo;existent pas ?</strong><br />
En effet, la colonne contient entre une et huit sous-chaînes selon la ligne. Comment générer une ligne par sous-chaîne à partir d&rsquo;une ligne source dans la requête SQL ?<br />
Pour ce faire, on s&rsquo;appuie sur le fait qu&rsquo;une relation 1-n entre deux tables génère n lignes dans une requête.</p>
<p>Connaissant le nombre de sous-chaîne, il nous faut donc créer une table de chiffres que l&rsquo;on mettra en relation avec ce nombre pour générer les lignes.</p>
<p>Cette fonction créée pour vous la table tChiffres et ajoute une ligne par chiffre (0 à 9)</p>
<div class="codecolorer-container vb blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="vb codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #E56717; font-weight: bold;">Public</span> <span style="color: #E56717; font-weight: bold;">Function</span> CreationTableChiffres() <br />
&nbsp; &nbsp;Const cInsert <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span> = <span style="color: #800000;">&quot;INSERT INTO tChiffres (Chiffre) VALUES &quot;</span> <br />
&nbsp; &nbsp;<span style="color: #151B8D; font-weight: bold;">Dim</span> i <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Long</span> <br />
&nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">With</span> DoCmd <br />
&nbsp; &nbsp; &nbsp; .SetWarnings <span style="color: #00C2FF; font-weight: bold;">False</span> <br />
&nbsp; &nbsp; &nbsp; .RunSQL <span style="color: #800000;">&quot;CREATE TABLE tChiffres (Chiffre LONG CONSTRAINT PrimaryKey PRIMARY KEY);&quot;</span> <br />
&nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">For</span> i = 0 <span style="color: #8D38C9; font-weight: bold;">To</span> 9 <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.RunSQL cInsert &amp; <span style="color: #800000;">&quot;(&quot;</span> &amp; i &amp; <span style="color: #800000;">&quot;)&quot;</span> <br />
&nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">Next</span> i <br />
&nbsp; &nbsp; &nbsp; .SetWarnings <span style="color: #00C2FF; font-weight: bold;">True</span> <br />
&nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">With</span> <br />
&nbsp;<br />
&nbsp; &nbsp;MsgBox <span style="color: #800000;">&quot;Création terminée de la table &quot;</span> <br />
<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #E56717; font-weight: bold;">Function</span></div></div>
<p>Par exemple, la requête SQL suivante génére tous les nombres entre 0 et 999 :</p>
<div class="codecolorer-container sql blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">SELECT</span> C1<span style="color: #66cc66;">.</span>chiffre <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">100</span> <span style="color: #66cc66;">+</span> C2<span style="color: #66cc66;">.</span>chiffre <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">10</span> <span style="color: #66cc66;">+</span> C3<span style="color: #66cc66;">.</span>chiffre <span style="color: #993333; font-weight: bold;">AS</span> Nombre<br />
<span style="color: #993333; font-weight: bold;">FROM</span> tchiffres C1<span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp;tchiffres C2<span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp;tchiffres C3</div></div>
<p>Dans notre cas, nous avons au maximum 8 sous-chaînes, donc la première partie de notre requête s&rsquo;écrira :</p>
<div class="codecolorer-container sql blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #66cc66;">...</span><span style="color: #993333; font-weight: bold;">FROM</span> <span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> Texte<span style="color: #66cc66;">,</span> CompteOccurrences<span style="color: #66cc66;">&#40;</span>Texte<span style="color: #66cc66;">,</span><span style="color: #ff0000;">&quot;@&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">+</span><span style="color: #cc66cc;">1</span> <span style="color: #993333; font-weight: bold;">AS</span> Compte <span style="color: #993333; font-weight: bold;">FROM</span> tTransposition<span style="color: #66cc66;">&#41;</span> T <span style="color: #993333; font-weight: bold;">INNER</span> <span style="color: #993333; font-weight: bold;">JOIN</span> tChiffres C <span style="color: #993333; font-weight: bold;">ON</span> T<span style="color: #66cc66;">.</span>Compte<span style="color: #66cc66;">&gt;</span>C<span style="color: #66cc66;">.</span>Chiffre<span style="color: #66cc66;">...</span></div></div>
<p>Ceci permettra d&rsquo;associer un chiffre à chaque sous-chaîne extraite.</p>
<p><strong>Extraire les sous-chaînes</strong><br />
La fonction Token(&#8230;) a pour argument le numéro (<strong>1</strong> à x) de la sous-chaîne à extraire. Il faut donc ajouter 1 aux chiffres retournés par la relation précédente.<br />
La clause FROM de notre requête est maintenant formée :</p>
<div class="codecolorer-container sql blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #66cc66;">...</span><span style="color: #993333; font-weight: bold;">FROM</span> <span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> Token<span style="color: #66cc66;">&#40;</span>Texte<span style="color: #66cc66;">,</span><span style="color: #ff0000;">&quot;@&quot;</span><span style="color: #66cc66;">,</span>Chiffre<span style="color: #66cc66;">+</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> Chaine <span style="color: #993333; font-weight: bold;">FROM</span> <span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> Texte<span style="color: #66cc66;">,</span> CompteOccurrences<span style="color: #66cc66;">&#40;</span>Texte<span style="color: #66cc66;">,</span><span style="color: #ff0000;">&quot;@&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">+</span><span style="color: #cc66cc;">1</span> <span style="color: #993333; font-weight: bold;">AS</span> Compte <span style="color: #993333; font-weight: bold;">FROM</span> tTransposition<span style="color: #66cc66;">&#41;</span> &nbsp;<span style="color: #993333; font-weight: bold;">AS</span> T <span style="color: #993333; font-weight: bold;">INNER</span> <span style="color: #993333; font-weight: bold;">JOIN</span> tChiffres <span style="color: #993333; font-weight: bold;">AS</span> C <span style="color: #993333; font-weight: bold;">ON</span> T<span style="color: #66cc66;">.</span>Compte<span style="color: #66cc66;">&gt;</span>C<span style="color: #66cc66;">.</span>Chiffre<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> R<span style="color: #66cc66;">...</span></div></div>
<p><strong>Requête finale</strong><br />
Finalement, on réalise un regroupement sur les chaînes et un comptage décroissant :</p>
<div class="codecolorer-container sql blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">SELECT</span> R<span style="color: #66cc66;">.</span>chaine<span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">COUNT</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">*</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> Compte<br />
<span style="color: #993333; font-weight: bold;">FROM</span> &nbsp;<span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> Token<span style="color: #66cc66;">&#40;</span>texte<span style="color: #66cc66;">,</span> <span style="color: #ff0000;">&quot;@&quot;</span><span style="color: #66cc66;">,</span> chiffre <span style="color: #66cc66;">+</span> <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> Chaine<br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">FROM</span> <span style="color: #66cc66;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">SELECT</span> texte<span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Compteoccurrences<span style="color: #66cc66;">&#40;</span>texte<span style="color: #66cc66;">,</span> <span style="color: #ff0000;">&quot;@&quot;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">+</span> <span style="color: #cc66cc;">1</span> <span style="color: #993333; font-weight: bold;">AS</span> Compte<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">FROM</span> ttransposition<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> T<br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">INNER</span> <span style="color: #993333; font-weight: bold;">JOIN</span> tchiffres <span style="color: #993333; font-weight: bold;">AS</span> C<br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">ON</span> T<span style="color: #66cc66;">.</span>compte <span style="color: #66cc66;">&gt;</span> C<span style="color: #66cc66;">.</span>chiffre<br />
&nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> R<br />
<span style="color: #993333; font-weight: bold;">GROUP</span> <span style="color: #993333; font-weight: bold;">BY</span> R<span style="color: #66cc66;">.</span>chaine<br />
<span style="color: #993333; font-weight: bold;">ORDER</span> <span style="color: #993333; font-weight: bold;">BY</span> <span style="color: #993333; font-weight: bold;">COUNT</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">*</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">DESC</span>;</div></div>
<p><strong>Pour ne pas plomber la vitesse d&rsquo;exécution </strong>de la requête, l&rsquo;enregistrer, quitter l&rsquo;application Access, la redémarrer puis lancer la requête SQL sans ouvrir auparavant l&rsquo;éditeur VBA.<br />
En moins de 2 secondes, le résultat de la requête devrait s&rsquo;afficher.<br />
A noter que le texte des lignes est généré aléatoirement d&rsquo;où certainement des écarts entre les comptages de la capture d&rsquo;écran et les vôtres.</p>
<p><strong>Requête SQL sans UDF</strong><br />
Si le coeur vous en dit, la requête suivante réalise le même travail sans utiliser une fonction personnelle.<br />
Mis à part les fonctions VBA déjà décrites dans ce blog, on utilise la fonction StrReverse() pour supprimer les séparateurs postérieurs à la sous-chaîne à extraire et déterminer ainsi sa longueur.</p>
<div class="codecolorer-container sql blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">SELECT</span> &nbsp;R<span style="color: #66cc66;">.</span>Chaine<span style="color: #66cc66;">,</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">COUNT</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">*</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> Compte<br />
<span style="color: #993333; font-weight: bold;">FROM</span> &nbsp; &nbsp;<span style="color: #66cc66;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">SELECT</span> IIf<span style="color: #66cc66;">&#40;</span>Num<span style="color: #66cc66;">&gt;</span><span style="color: #cc66cc;">1</span> <span style="color: #993333; font-weight: bold;">AND</span> NUM1<span style="color: #66cc66;">,</span> <span style="color: #993333; font-weight: bold;">LEFT</span>$<span style="color: #66cc66;">&#40;</span>T<span style="color: #66cc66;">.</span>Texte<span style="color: #66cc66;">,</span>InStr<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,</span>T<span style="color: #66cc66;">.</span>Texte<span style="color: #66cc66;">,</span><span style="color: #ff0000;">&quot;@&quot;</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">-</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>T<span style="color: #66cc66;">.</span>Texte<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; MID$<span style="color: #66cc66;">&#40;</span>T<span style="color: #66cc66;">.</span>Texte<span style="color: #66cc66;">,</span>InStrRev<span style="color: #66cc66;">&#40;</span>T<span style="color: #66cc66;">.</span>Texte<span style="color: #66cc66;">,</span><span style="color: #ff0000;">&quot;@&quot;</span><span style="color: #66cc66;">,-</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">+</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> Chaine<span style="color: #66cc66;">,</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Chiffre<span style="color: #66cc66;">+</span><span style="color: #cc66cc;">1</span> <span style="color: #993333; font-weight: bold;">AS</span> Num <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">FROM</span> <span style="color: #66cc66;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">SELECT</span> Texte<span style="color: #66cc66;">,</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Len<span style="color: #66cc66;">&#40;</span>Texte<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">-</span> Len<span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">REPLACE</span><span style="color: #66cc66;">&#40;</span>Texte<span style="color: #66cc66;">,</span><span style="color: #ff0000;">&quot;@&quot;</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">&quot;&quot;</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,-</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">+</span><span style="color: #cc66cc;">1</span> <span style="color: #993333; font-weight: bold;">AS</span> Compte <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">FROM</span> tTransposition<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#41;</span> &nbsp;<span style="color: #993333; font-weight: bold;">AS</span> T <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">INNER</span> <span style="color: #993333; font-weight: bold;">JOIN</span> tChiffres <span style="color: #993333; font-weight: bold;">AS</span> C <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">ON</span> T<span style="color: #66cc66;">.</span>Compte<span style="color: #66cc66;">&gt;</span>C<span style="color: #66cc66;">.</span>Chiffre<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#41;</span> &nbsp;<span style="color: #993333; font-weight: bold;">AS</span> R<br />
<span style="color: #993333; font-weight: bold;">GROUP</span> <span style="color: #993333; font-weight: bold;">BY</span> R<span style="color: #66cc66;">.</span>Chaine<br />
<span style="color: #993333; font-weight: bold;">ORDER</span> <span style="color: #993333; font-weight: bold;">BY</span> <span style="color: #993333; font-weight: bold;">COUNT</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">*</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">DESC</span>;</div></div>
<p><strong>Lien</strong><br />
Voir ce <a href="http://blog.developpez.com/philben/p11320/ms-access-vba/transposer-des-lignes-en-une-colonne" title="Transposer des lignes en une colonne">billet</a> pour réaliser une transposition inverse.</p>
<p>@+</p>
<p>Philippe</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Extraction d&#8217;une sous-chaîne délimitée par deux séparateurs différents</title>
		<link>https://blog.developpez.com/philben/p11113/vba-access/extraction_d_une_sous_chaine_delimitee</link>
		<comments>https://blog.developpez.com/philben/p11113/vba-access/extraction_d_une_sous_chaine_delimitee#comments</comments>
		<pubDate>Sun, 01 Jul 2012 17:09:36 +0000</pubDate>
		<dc:creator><![CDATA[philben]]></dc:creator>
				<category><![CDATA[SQL - Ms Access]]></category>
		<category><![CDATA[VBA - Ms Access]]></category>
		<category><![CDATA[Chaîne de caractères]]></category>
		<category><![CDATA[Code VBA]]></category>
		<category><![CDATA[Requête SQL]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Un camarade de jeu souhaitait extraire d&#8217;une table, une chaîne de caractères délimitée par deux séparateurs (Token in english!) via une requête SQL. Deux solutions sont présentées : L&#8217;une par utilisation d&#8217;une fonction personnelle en VBA (UDF : User-Defined-Function) et &#8230; <a href="https://blog.developpez.com/philben/p11113/vba-access/extraction_d_une_sous_chaine_delimitee">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Un camarade de jeu souhaitait extraire d&rsquo;une table, une chaîne de caractères délimitée par deux séparateurs (Token in english!) via une requête SQL.<br />
Deux solutions sont présentées : L&rsquo;une par utilisation d&rsquo;une fonction personnelle en VBA (UDF : User-Defined-Function) et l&rsquo;autre sans UDF via des fonctions standards VBA.<br />
<span id="more-28"></span><br />
<strong>Cahier des charges</strong></p>
<ul>
<li>La table contient 100 000 lignes : Va falloir être performant sur le coup !</li>
<li>La colonne de texte ne contient aucun NULL : Tant mieux, une source de problèmes en moins&#8230;</li>
<li>Les séparateurs du token sont toujours présents : Nickel, on évite des tests supplémentaires&#8230;</li>
<li>Il peut y avoir plus de deux séparateurs dans le texte, dans ce cas, prendre la sous-chaine entourée par les séparateurs extrêmes : Il faudra trouver une méthode pour faire abstraction des séparateurs parasites&#8230;</li>
<li>Les séparateurs sont &lsquo;[&lsquo; et &lsquo;]&rsquo; : Bien, on va pouvoir faire des comparaisons binaires qui sont les plus performantes&#8230;</li>
<li>Les deux délimiteurs peuvent être côte à côte : Ok, faudra vérifier ce cas particulier avec l&rsquo;algorithme.</li>
<li>Le nombre de caractères dans le texte est variable ainsi que la position des séparateurs : Ben, Il faudra les rechercher&#8230;</li>
<li>Version 2007 d&rsquo;Access : Reconnaît les fonctions VBA &lsquo;modernes&rsquo;</li>
</ul>
<p><strong>Exemples suite au cahier des charges</strong></p>
<div class="codecolorer-container text geshi" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">'a[SC]bc' -&gt; 'SC'<br />
'[SC]' &nbsp; &nbsp;-&gt; 'SC'<br />
'ab[S[]]' -&gt; 'S[]'<br />
'ab[]cd' &nbsp;-&gt; ''</div></div>
<p>&nbsp;<br />
<strong>Création de la table et des lignes</strong><br />
Cette fonction créée la table tToken et 100 000 lignes. Peut prendre plusieurs secondes selon le système.<br />
La table possède une colonne LenToken qui permettra de vérifier, via une requête, la qualité des résultats.</p>
<p>Pour l&rsquo;utiliser, copier l&rsquo;ensemble du code dans un module VBA, placer le focus dans la fonction &lsquo;CreationTableToken()&rsquo; puis appuyer sur &lsquo;F5&prime; pour l&rsquo;exécuter.</p>
<div class="codecolorer-container vb blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:400px;"><div class="vb codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #E56717; font-weight: bold;">Public</span> <span style="color: #E56717; font-weight: bold;">Function</span> CreationTableToken() <br />
&nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">With</span> DoCmd <br />
&nbsp; &nbsp; &nbsp; .SetWarnings <span style="color: #00C2FF; font-weight: bold;">False</span> <br />
&nbsp; &nbsp; &nbsp; .RunSQL <span style="color: #800000;">&quot;CREATE TABLE tToken (Texte CHAR NOT NULL, LenToken LONG);&quot;</span> <br />
&nbsp; &nbsp; &nbsp; .SetWarnings <span style="color: #00C2FF; font-weight: bold;">True</span> <br />
&nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">With</span> <br />
&nbsp; &nbsp;GenereTokens <br />
&nbsp;<br />
&nbsp; &nbsp;MsgBox <span style="color: #800000;">&quot;Création terminée&quot;</span> <br />
<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #E56717; font-weight: bold;">Function</span> <br />
&nbsp;<br />
<span style="color: #E56717; font-weight: bold;">Private</span> <span style="color: #E56717; font-weight: bold;">Function</span> GenereTokens() <br />
&nbsp; &nbsp;Const clMaxLignes <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Long</span> = 100000 <br />
&nbsp; &nbsp;Const cHorsTokenASCII <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Long</span> = 95 <br />
&nbsp; &nbsp;Const cTokenASCII <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Long</span> = 84 <br />
&nbsp; &nbsp;Const cCrochetGauche <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span> = <span style="color: #800000;">&quot;[&quot;</span> <br />
&nbsp; &nbsp;Const cCrochetDroite <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span> = <span style="color: #800000;">&quot;]&quot;</span> <br />
&nbsp;<br />
&nbsp; &nbsp;<span style="color: #151B8D; font-weight: bold;">Dim</span> odb <span style="color: #151B8D; font-weight: bold;">As</span> DAO.Database <br />
&nbsp; &nbsp;<span style="color: #151B8D; font-weight: bold;">Dim</span> ors <span style="color: #151B8D; font-weight: bold;">As</span> DAO.Recordset <br />
&nbsp; &nbsp;<span style="color: #151B8D; font-weight: bold;">Dim</span> Texte <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span> <br />
&nbsp; &nbsp;<span style="color: #151B8D; font-weight: bold;">Dim</span> i <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Long</span>, l <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Long</span>, x <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Long</span>, y <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Long</span> <br />
&nbsp;<br />
&nbsp; &nbsp;<span style="color: #151B8D; font-weight: bold;">Set</span> odb = CurrentDb <br />
&nbsp; &nbsp;<span style="color: #151B8D; font-weight: bold;">Set</span> ors = odb.OpenRecordset(<span style="color: #800000;">&quot;tToken&quot;</span>, dbOpenDynaset) <br />
&nbsp; &nbsp;Randomize <br />
&nbsp;<br />
&nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">With</span> ors <br />
&nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">For</span> i = 1 <span style="color: #8D38C9; font-weight: bold;">To</span> clMaxLignes <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #008000;">'construction du texte <br />
</span> &nbsp; &nbsp; &nbsp; &nbsp; l = Int(Rnd() * 254) + 2 &nbsp; <span style="color: #008000;">'longueur variable du texte : 2 à 255 <br />
</span> &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">Do</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; x = Int(l * Rnd()) + 1 <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; y = Int(l * Rnd()) + 1 <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">Loop</span> <span style="color: #8D38C9; font-weight: bold;">Until</span> x &nbsp;x + 1 <span style="color: #8D38C9; font-weight: bold;">Then</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">While</span> Rnd() &lt; 0.5 <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Mid$(Texte, Int((y - x - 1) * Rnd()) + x + 1, 1) = IIf(Rnd() &nbsp;1 <span style="color: #8D38C9; font-weight: bold;">Then</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">While</span> Rnd() &lt; 0.5 <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Mid$(Texte, Int((x - 1) * Rnd()) + 1, 1) = cCrochetDroite <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Wend <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">If</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">If</span> y &lt; l <span style="color: #8D38C9; font-weight: bold;">Then</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">While</span> Rnd() &lt; 0.5 <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Mid$(Texte, Int((l - y - 1) * Rnd()) + y + 1, 1) = cCrochetGauche <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Wend <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">If</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #008000;">'Ajout de la ligne <br />
</span> &nbsp; &nbsp; &nbsp; &nbsp; .AddNew <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;!Texte = Texte <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;!LenToken = y - x - 1 <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.Update <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">Next</span> i <br />
&nbsp; &nbsp; &nbsp; .<span style="color: #8D38C9; font-weight: bold;">Close</span> <br />
&nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">With</span> <br />
&nbsp;<br />
&nbsp; &nbsp;<span style="color: #151B8D; font-weight: bold;">Set</span> ors = <span style="color: #00C2FF; font-weight: bold;">Nothing</span> <br />
&nbsp; &nbsp;<span style="color: #151B8D; font-weight: bold;">Set</span> odb = <span style="color: #00C2FF; font-weight: bold;">Nothing</span> <br />
<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #E56717; font-weight: bold;">Function</span></div></div>
<p>&nbsp;<br />
<strong>La trousse à outils VBA</strong><br />
Rapide inventaire des fonctions VBA qui permettent d&rsquo;extraire une sous-chaîne :</p>
<ul>
<li>Left(Texte, Longueur) et Right(&#8230;) : Permettent d&rsquo;extraire la partie gauche ou droite d&rsquo;un texte.</li>
<li>Mid(Texte, Début, Longueur) : Permet d&rsquo;extraire une partie quelconque d&rsquo;un texte</li>
<li>Split(Texte, séparateur,&#8230;) : Retourne dans un tableau de base zéro le texte scindé par le séparateur .</li>
<li>Replace(Texte, Recherche, Remplacement,&#8230;) : Ce n&rsquo;est pas son usage habituel mais si on connait le texte à retirer, on peut le remplacer par une chaîne vide et ne conserver que la sous-chaîne désirée&#8230;</li>
</ul>
<p>La fonction Len(&#8230;) permet de compter les caractères d&rsquo;une chaîne.</p>
<p>Les fonctions VBA pour déterminer la position d&rsquo;une sous-chaîne :</p>
<ul>
<li>InStr([Début],Texte, Recherche,&#8230;) : Renvoie la position de la première occurrence de Recherche à partir du début du Texte</li>
<li>InStrRev(Texte, Recherche,&#8230;) : Renvoie la première occurrence de Recherche à partir de la fin du Texte.</li>
</ul>
<p><strong>Remarque</strong><br />
Certaines fonctions existent avec $ en suffixe de leur nom (Left$(),&#8230;) : Ceci veut dire qu&rsquo;elles vont retourner une variable de type String (chaîne de caractères) et non un Variant qui peut être NULL ou typé (String, Date).</p>
<p>Liste des fonctions qui retournent un type String (parfois, elles ont un argument String au lieu de Variant)  :</p>
<div class="codecolorer-container text geshi" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Chr$(), &nbsp; &nbsp; ChrB$(), &nbsp;ChrW$(), &nbsp; Command$(), CurDir$(), Date$(), &nbsp; Dir$(),<br />
Environ$(), Error$(), Format$(), Hex$(), &nbsp; &nbsp; Input$(), &nbsp;InputB$(), LCase$(),<br />
Left$(), &nbsp; &nbsp;LeftB$(), LTrim$(), &nbsp;Mid$(), &nbsp; &nbsp; MidB$(), &nbsp; Oct$(), &nbsp; &nbsp;Right$(),<br />
RightB$(), &nbsp;RTrim$(), Space$(), &nbsp;Str$(), &nbsp; &nbsp; String$(), Time$(), &nbsp; Trim$(),<br />
UCase$()</div></div>
<p>&nbsp;<br />
<em>Comment choisir entre $ ou non ?</em><br />
Si on souhaite propager un NULL ou retourner un variant de type Date (fonction Time(), Date()) il faudra donc utiliser la version <strong>sans</strong> $.<br />
Par contre, si on recherche la performance ET que l&rsquo;on ne passe pas un NULL à la fonction$ (une erreur est levée dans ce cas) ET que l&rsquo;on souhaite récupérer une variable de type caractère, il est préférable d&rsquo;utiliser les fonctions avec $. Le gain de rapidité de fonction$() peut atteindre 40% par rapport à son équivalent !</p>
<p><strong>Construction de la fonction VBA</strong><br />
D&rsquo;après le cahier des charges, la colonne de la table ne contient pas de NULL, donc on peut écrire une fonction qui aura en paramètre un type String et retournera aussi un type String (performance meilleure).<br />
Dans ce cas, on pourra utiliser les fonctions équivalentes Fonction<strong>$</strong>() pour un gain de performance.</p>
<p>On ne pourra pas utiliser Split() car il faut seulement prendre les séparateurs extrêmes si il en existe plusieurs. Split() couperait la chaîne autant de fois qu&rsquo;il y a de séparateurs&#8230;<br />
Il faudra donc utiliser une fois InStr() pour trouver le premier séparateur et InStrRev() pour positionner le dernier.</p>
<p>Les séparateurs peuvent être n&rsquo;importe où dans le texte, la seule fonction qui permette de récupérer une sous-chaîne dans ce cas est Mid().</p>
<p>La fonction &lsquo;spécifique&rsquo; à la demande est :</p>
<div class="codecolorer-container vb blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="vb codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #E56717; font-weight: bold;">Public</span> <span style="color: #E56717; font-weight: bold;">Function</span> MyToken(<span style="color: #151B8D; font-weight: bold;">ByVal</span> Texte <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span>) <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span> <br />
&nbsp; &nbsp; <span style="color: #151B8D; font-weight: bold;">Dim</span> x <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Long</span> <br />
&nbsp; &nbsp; x = InStr(1, Texte, <span style="color: #800000;">&quot;[&quot;</span>, vbBinaryCompare) + 1 <br />
&nbsp; &nbsp; MyToken = Mid$(Texte, x, InStrRev(Texte, <span style="color: #800000;">&quot;]&quot;</span>, -1, vbBinaryCompare) - x) <br />
<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #E56717; font-weight: bold;">Function</span></div></div>
<p>On affecte à la variable x la position du séparateur &lsquo;[&lsquo; le plus à gauche dans la chaîne. On lui ajoute 1 car ceci évite deux additions par la suite.<br />
On remarque que InStr est utilisé ici dans sa version &lsquo;longue&rsquo; (InStr(<strong>Depart</strong>, Texte, Recherche, Comparaison)) car on impose le type de comparaison. Si on ne l&rsquo;impose pas on peut écrire InStr(Texte, Recherche).<br />
La ligne suivante va extraire la sous-chaîne du Texte grâce à l&rsquo;utilisation de la fonction Mid$().<br />
Le deuxième argument (x) de Mid() détermine le point de départ de la sous-chaîne (position du séparateur gauche + 1).<br />
Le troisième argument est une <strong>longueur</strong>, il nous faut donc déterminer la position du séparateur à droite de la sous-chaîne en utilisant InStrRev() et retrancher la position de départ (x).</p>
<p>Ci-dessous la même fonction mais plus polyvalente car gère l&rsquo;absence d&rsquo;un ou des séparateurs et le cas des chaînes vides :</p>
<div class="codecolorer-container vb blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="vb codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #E56717; font-weight: bold;">Public</span> <span style="color: #E56717; font-weight: bold;">Function</span> MyToken2(<span style="color: #151B8D; font-weight: bold;">ByVal</span> Texte <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span>, <span style="color: #151B8D; font-weight: bold;">ByVal</span> SeparateurGauche <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span>, <span style="color: #151B8D; font-weight: bold;">ByVal</span> SeparateurDroite <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span>, <span style="color: #151B8D; font-weight: bold;">Optional</span> <span style="color: #151B8D; font-weight: bold;">ByVal</span> TypeComparaison <span style="color: #151B8D; font-weight: bold;">As</span> VbCompareMethod = vbBinaryCompare) <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span> <br />
&nbsp; &nbsp;<span style="color: #151B8D; font-weight: bold;">Dim</span> x <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Long</span>, y <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Long</span> <br />
&nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">If</span> Texte &lt;&gt; vbNullString <span style="color: #8D38C9; font-weight: bold;">Then</span> &nbsp; <span style="color: #008000;">'Test intéressant en terme de performance si de nombreux textes sont des chaînes vides <br />
</span> &nbsp; &nbsp; &nbsp;x = InStr(1, Texte, SeparateurGauche, TypeComparaison) <br />
&nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">If</span> x &gt; 0 <span style="color: #8D38C9; font-weight: bold;">Then</span> &nbsp; <span style="color: #008000;">'Test intéressant en terme de performance si le séparateur gauche n'est pas toujours présent <br />
</span> &nbsp; &nbsp; &nbsp; &nbsp; y = InStrRev(Texte, SeparateurDroite, -1, TypeComparaison) <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #008000;">'Test nécessaire sinon une erreur peut être levée <br />
</span> &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">If</span> y &gt; x <span style="color: #8D38C9; font-weight: bold;">Then</span> MyToken2 = Mid$(Texte, x + 1, y - x - 1) <br />
&nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">If</span> <br />
&nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">If</span> <br />
<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #E56717; font-weight: bold;">Function</span></div></div>
<p>&nbsp;<br />
Enfin, la même fonction mais avec un argument et une valeur retournée de type Variant pour propager les NULL.</p>
<div class="codecolorer-container vb blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="vb codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #E56717; font-weight: bold;">Public</span> <span style="color: #E56717; font-weight: bold;">Function</span> MyToken3(<span style="color: #151B8D; font-weight: bold;">ByVal</span> Texte <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Variant</span>, <span style="color: #151B8D; font-weight: bold;">ByVal</span> SeparateurGauche <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span>, <span style="color: #151B8D; font-weight: bold;">ByVal</span> SeparateurDroite <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span>, <span style="color: #151B8D; font-weight: bold;">Optional</span> <span style="color: #151B8D; font-weight: bold;">ByVal</span> TypeComparaison <span style="color: #151B8D; font-weight: bold;">As</span> VbCompareMethod = vbBinaryCompare) <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Variant</span> <br />
&nbsp; &nbsp;<span style="color: #151B8D; font-weight: bold;">Dim</span> x <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Long</span>, y <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Long</span> <br />
&nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">If</span> Len(Nz(Texte,<span style="color: #800000;">&quot;&quot;</span>)) &gt; 0 <span style="color: #8D38C9; font-weight: bold;">Then</span> &nbsp; <span style="color: #008000;">'Test nécessaire car InStr peut retourner Null et x est de type Long, InStrRev n'accepte pas un texte NULL <br />
</span> &nbsp; &nbsp; &nbsp;x = InStr(1, Texte, SeparateurGauche, TypeComparaison) <br />
&nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">If</span> x &gt; 0 <span style="color: #8D38C9; font-weight: bold;">Then</span> &nbsp; <span style="color: #008000;">'Test intéressant en terme de performance si le séparateur gauche n'est pas toujours présent <br />
</span> &nbsp; &nbsp; &nbsp; &nbsp; y = InStrRev(Texte, SeparateurDroite, -1, TypeComparaison) <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #008000;">'Test nécessaire sinon une erreur peut être levée <br />
</span> &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">If</span> y &gt; x <span style="color: #8D38C9; font-weight: bold;">Then</span> MyToken3 = Mid(Texte, x + 1, y - x - 1) <br />
&nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">If</span> <br />
&nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">If</span> <br />
<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #E56717; font-weight: bold;">Function</span></div></div>
<p>On remarquera l&rsquo;utilisation de la fonction Nz() qui retourne une valeur de notre choix si son argument est NULL.<br />
Pour info, InStr() ne lève pas d&rsquo;erreur si Texte est NULL contrairement à InStrRev&#8230;</p>
<p>et pour finir, la requête SQL via l&rsquo;UDF MyToken():</p>
<div class="codecolorer-container sql blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">SELECT</span> Mytoken<span style="color: #66cc66;">&#40;</span>texte<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> Token<span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;ttoken<span style="color: #66cc66;">.</span>lentoken <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #66cc66;">&#91;</span>Longueur théorique Token<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;Len<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#91;</span>token<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #66cc66;">&#91;</span>Longueur trouvée<span style="color: #66cc66;">&#93;</span><br />
<span style="color: #993333; font-weight: bold;">FROM</span> &nbsp; ttoken</div></div>
<p>&nbsp;<br />
<strong>Fonction directement dans le SQL</strong><br />
Le principe repose sur l&rsquo;utilisation de la fonction Mid() et intuitivement on peut écrire le template de la fonction : <code class="codecolorer sql blackboard"><span class="sql">Mid<span style="color: #66cc66;">&#40;</span>Texte<span style="color: #66cc66;">,</span> InStr<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span> InStrRev<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">-</span> InStr<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></span></code>.<br />
Le reproche qui saute aux yeux est qu&rsquo;on utilise deux fois la fonction InStr(). Bien que plus performante que InStrRev(), elle est tout de même plus consommatrice de temps CPU que Left(), Right() Mid().<br />
Pour se débarrasser de ce deuxième InStr(), on peut s&rsquo;appuyer sur une particularité de Mid(). En effet, le troisième paramètre de Mid() est optionnel. Si on ne renseigne pas la longueur de la chaîne retournée, Mid() retourne toute la chaîne à partir du point de départ.<br />
Il faut donc dans le premier argument de Mid() passer une chaîne déjà limitée à droite.<br />
Voici le nouveau template de notre fonction : <code class="codecolorer sql blackboard"><span class="sql">Mid<span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">LEFT</span><span style="color: #66cc66;">&#40;</span>Texte<span style="color: #66cc66;">,</span>InStrRev<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>InStr<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></span></code>.</p>
<p>Ensuite, il faut travailler sur la performance car on utilise tout de même 4 fonctions au lieu de 3 dans MyToken(). Dans le cas exposé ici, on utilisera les fonctions avec $ et on imposera la comparaison binaire.</p>
<p>La requête SQL est :</p>
<div class="codecolorer-container sql blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">SELECT</span> Mid$<span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">LEFT</span>$<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#91;</span>texte<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">,</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Instrrev<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#91;</span>texte<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">&quot;]&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">-</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">-</span> <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Instr<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">&#91;</span>texte<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">&quot;[&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">+</span> <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">AS</span> Token<span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;ttoken<span style="color: #66cc66;">.</span>lentoken <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #66cc66;">&#91;</span>Longueur théorique Token<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;Len<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#91;</span>token<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #66cc66;">&#91;</span>Longueur trouvée<span style="color: #66cc66;">&#93;</span><br />
<span style="color: #993333; font-weight: bold;">FROM</span> ttoken</div></div>
<p>&nbsp;<br />
<strong>Performance et qualité</strong><br />
Avant de tester les performances, quitter normalement l&rsquo;application Access puis la relancer sans ouvrir l&rsquo;éditeur VBA pour ne pas pénaliser la requête avec l&rsquo;UDF.</p>
<p>Les requêtes suivantes retournent les lignes dont la longueur théorique du token est différente de la longueur calculée (aucune ligne retournée normalement !).</p>
<p>La requête via l&rsquo;UDF MyToken (plus performante a priori&#8230;)</p>
<div class="codecolorer-container sql blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">SELECT</span> Mytoken<span style="color: #66cc66;">&#40;</span>texte<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> Token<span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;ttoken<span style="color: #66cc66;">.</span>lentoken <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #66cc66;">&#91;</span>Longueur théorique Token<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;Len<span style="color: #66cc66;">&#40;</span>token<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #66cc66;">&#91;</span>Longueur trouvée<span style="color: #66cc66;">&#93;</span><br />
<span style="color: #993333; font-weight: bold;">FROM</span> &nbsp; ttoken<br />
<span style="color: #993333; font-weight: bold;">WHERE</span> &nbsp;Len<span style="color: #66cc66;">&#40;</span>Mytoken<span style="color: #66cc66;">&#40;</span>texte<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> &nbsp;lentoken;</div></div>
<p>&nbsp;<br />
Et la même requête avec la fonction directement dans le code SQL :</p>
<div class="codecolorer-container sql blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">SELECT</span> Mid$<span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">LEFT</span>$<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#91;</span>texte<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">,</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Instrrev<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#91;</span>texte<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">&quot;]&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">-</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">-</span> <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Instr<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">&#91;</span>texte<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">&quot;[&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">+</span> <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">AS</span> Token<span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;ttoken<span style="color: #66cc66;">.</span>lentoken <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #66cc66;">&#91;</span>Longueur théorique Token<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;Len<span style="color: #66cc66;">&#40;</span>token<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #66cc66;">&#91;</span>Longueur trouvée<span style="color: #66cc66;">&#93;</span><br />
<span style="color: #993333; font-weight: bold;">FROM</span> &nbsp; ttoken<br />
<span style="color: #993333; font-weight: bold;">WHERE</span> &nbsp;Len<span style="color: #66cc66;">&#40;</span>Mid$<span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">LEFT</span>$<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#91;</span>texte<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">,</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Instrrev<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#91;</span>texte<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">&quot;]&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">-</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">-</span> <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Instr<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">&#91;</span>texte<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">&quot;[&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">+</span> <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> &nbsp;lentoken;</div></div>
<p>&nbsp;<br />
<strong>Lien</strong><br />
Voir <a href="http://blog.developpez.com/philben/p11126/ms-access-vba/extraire_un_token_d_une_chaine" title="Extraire un token d’une chaîne de caractères" target="_blank">ce billet</a> pour extraire des token délimités par un seul séparateur.<br />
&nbsp;<br />
@+</p>
<p>Philippe</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Compter les occurrences d&#8217;une sous-chaine dans un texte</title>
		<link>https://blog.developpez.com/philben/p11099/vba-access/compter_les_occurrences_d_une_sous_chain</link>
		<comments>https://blog.developpez.com/philben/p11099/vba-access/compter_les_occurrences_d_une_sous_chain#comments</comments>
		<pubDate>Sun, 17 Jun 2012 20:50:22 +0000</pubDate>
		<dc:creator><![CDATA[philben]]></dc:creator>
				<category><![CDATA[SQL - Ms Access]]></category>
		<category><![CDATA[VBA - Ms Access]]></category>
		<category><![CDATA[Chaîne de caractères]]></category>
		<category><![CDATA[Code VBA]]></category>
		<category><![CDATA[Requête SQL]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[L&#8217;objectif est de compter les occurrences d&#8217;une chaîne de longueur quelconque en tenant compte ou non de la casse des caractères. Je vous présente ici deux techniques, l&#8217;une par une UDF (User-Defined Function) et l&#8217;autre directement en ligne dans la &#8230; <a href="https://blog.developpez.com/philben/p11099/vba-access/compter_les_occurrences_d_une_sous_chain">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>L&rsquo;objectif est de compter les occurrences d&rsquo;une chaîne de longueur quelconque en tenant compte ou non de la casse des caractères.<br />
Je vous présente ici deux techniques, l&rsquo;une par une UDF (User-Defined Function) et l&rsquo;autre directement en ligne dans la requête SQL.<br />
<span id="more-9"></span><br />
<strong>Création de la table et des ses lignes</strong><br />
Cette fontion créée la table tOccurrence qui est peuplée de 10 000 lignes de textes aléatoires.<br />
Pour l&rsquo;utiliser, copier l&rsquo;ensemble du code dans un module VBA, placer le focus dans la fonction &lsquo;CreationTableOccurrence()&rsquo; puis appuyer sur &lsquo;F5&prime; pour l&rsquo;exécuter.</p>
<div class="codecolorer-container vb blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:400px;"><div class="vb codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #E56717; font-weight: bold;">Public</span> <span style="color: #E56717; font-weight: bold;">Function</span> CreationTableOccurrence() <br />
&nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">With</span> DoCmd <br />
&nbsp; &nbsp; &nbsp; .SetWarnings <span style="color: #00C2FF; font-weight: bold;">False</span> <br />
&nbsp; &nbsp; &nbsp; .RunSQL <span style="color: #800000;">&quot;CREATE TABLE tOccurrence (Texte TEXT);&quot;</span> <br />
&nbsp; &nbsp; &nbsp; .SetWarnings <span style="color: #00C2FF; font-weight: bold;">True</span> <br />
&nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">With</span> <br />
&nbsp; &nbsp;GenereTextes <br />
&nbsp;<br />
&nbsp; &nbsp;MsgBox <span style="color: #800000;">&quot;Création terminée&quot;</span> <br />
<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #E56717; font-weight: bold;">Function</span> <br />
&nbsp;<br />
<span style="color: #E56717; font-weight: bold;">Private</span> <span style="color: #E56717; font-weight: bold;">Function</span> GenereTextes() <br />
&nbsp; &nbsp;Const clMaxLignes <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Long</span> = 10000 <br />
&nbsp; &nbsp;Const cMinAscii <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Long</span> = 32 &nbsp; <span style="color: #008000;">'= espace - chr(32) <br />
</span> &nbsp; Const cMaxAscii <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Long</span> = 122 - cMinAscii + 1 <br />
&nbsp;<br />
&nbsp; &nbsp;<span style="color: #151B8D; font-weight: bold;">Dim</span> odb <span style="color: #151B8D; font-weight: bold;">As</span> DAO.Database <br />
&nbsp; &nbsp;<span style="color: #151B8D; font-weight: bold;">Dim</span> ors <span style="color: #151B8D; font-weight: bold;">As</span> DAO.Recordset <br />
&nbsp; &nbsp;<span style="color: #151B8D; font-weight: bold;">Dim</span> Texte <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span> <br />
&nbsp; &nbsp;<span style="color: #151B8D; font-weight: bold;">Dim</span> i <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Long</span>, j <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Long</span>, l <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Long</span> <br />
&nbsp;<br />
&nbsp; &nbsp;<span style="color: #151B8D; font-weight: bold;">Set</span> odb = CurrentDb <br />
&nbsp; &nbsp;<span style="color: #151B8D; font-weight: bold;">Set</span> ors = odb.OpenRecordset(<span style="color: #800000;">&quot;tOccurrence&quot;</span>, dbOpenDynaset) <br />
&nbsp; &nbsp;Randomize <br />
&nbsp;<br />
&nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">With</span> ors <br />
&nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">For</span> i = 1 <span style="color: #8D38C9; font-weight: bold;">To</span> clMaxLignes <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;l = Int(Rnd() * 256) &nbsp; <span style="color: #008000;">'longueur variable du texte : 0 à 255 <br />
</span> &nbsp; &nbsp; &nbsp; &nbsp; Texte = <span style="color: #F660AB; font-weight: bold;">String</span>(l, Chr$(Int(cMaxAscii * Rnd()) + cMinAscii)) &nbsp; <span style="color: #008000;">'Génère le texte avec un caractère par défaut <br />
</span> &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">For</span> j = 1 <span style="color: #8D38C9; font-weight: bold;">To</span> Int(l * Rnd()) &nbsp; <span style="color: #008000;">' de 0 à longueur texte-1 modifications <br />
</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Mid$(Texte, Int(l * Rnd()) + 1, 1) = Chr$(Int(cMaxAscii * Rnd()) + cMinAscii) &nbsp; <span style="color: #008000;">'affecte un caractère à une position aléatoire <br />
</span> &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">Next</span> j <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.AddNew <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;!Texte = Texte <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.Update <br />
&nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">Next</span> i <br />
&nbsp; &nbsp; &nbsp; .<span style="color: #8D38C9; font-weight: bold;">Close</span> <br />
&nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">With</span> <br />
&nbsp;<br />
&nbsp; &nbsp;<span style="color: #151B8D; font-weight: bold;">Set</span> ors = <span style="color: #00C2FF; font-weight: bold;">Nothing</span> <br />
&nbsp; &nbsp;<span style="color: #151B8D; font-weight: bold;">Set</span> odb = <span style="color: #00C2FF; font-weight: bold;">Nothing</span> <br />
<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #E56717; font-weight: bold;">Function</span></div></div>
<p><strong>La technique via UDF</strong><br />
La fonction VBA utilise la fonction standard Split() qui génère un tableau (de base 0) de chaînes de caractères à partir d&rsquo;un texte en le découpant via un séparateur à définir.<br />
On peut définir le comportement de Split() en fonction de la casse des caractères grâce à son dernier paramètre optionnel :</p>
<ul>
<li>vbBinaryCompare (valeur = 0) : Comparaison binaire des caractères donc sensible à la casse</li>
<li>vbTextCompare (valeur = 1) : Comparaison textuelle donc insensible à la casse des caractères</li>
<li>vbDatabaseCompare (valeur = 2) : Comparaison en fonction de la configuration locale de windows</li>
</ul>
<p>Seules les valeurs 0 et 1 sont reproductibles d&rsquo;un système à l&rsquo;autre.</p>
<p>l&rsquo;UDF :</p>
<div class="codecolorer-container vb blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="vb codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #E56717; font-weight: bold;">Public</span> <span style="color: #E56717; font-weight: bold;">Function</span> CompteOccurrenceChaine(<span style="color: #151B8D; font-weight: bold;">ByVal</span> Texte <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span>, <span style="color: #151B8D; font-weight: bold;">ByVal</span> Chaine <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span>, <span style="color: #151B8D; font-weight: bold;">Optional</span> <span style="color: #151B8D; font-weight: bold;">ByVal</span> TypeComparaison <span style="color: #151B8D; font-weight: bold;">As</span> VbCompareMethod = vbBinaryCompare) <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Long</span> <br />
&nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">If</span> Texte &lt;&gt; vbNullString <span style="color: #8D38C9; font-weight: bold;">Then</span> CompteOccurrenceChaine = <span style="color: #151B8D; font-weight: bold;">UBound</span>(Split(Texte, Chaine, -1, TypeComparaison)) <br />
<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #E56717; font-weight: bold;">Function</span></div></div>
<p>Cette fonction demande 3 paramètres dont le dernier est optionnel.<br />
Le &lsquo;Texte&rsquo; dans lequel on souhaite compter le nombre de sous-chaîne &lsquo;Chaine&rsquo; et la méthode de comparaison qui est  binaire par défaut.<br />
La 1ère ligne du code retourne le plus grand indice de la dimension du tableau généré qui correspond donc au nombre d&rsquo;occurrences de la chaine. En effet, le texte &lsquo;A-B-C&rsquo; découpé sur &lsquo;-&lsquo; aura &lsquo;A&rsquo; en indice <strong>0</strong> du tableau généré, &lsquo;B&rsquo; en indice 1 et &lsquo;C&rsquo; en indice 2. L&rsquo;indice le plus grand est <strong>2</strong> ce qui correspond bien au nombre d&rsquo;occurrences de &lsquo;-&lsquo;.<br />
<strong>Que se passe t&rsquo;il si aucune occurrence n&rsquo;est trouvée ou si Chaine=&nbsp;&raquo;&nbsp;&raquo; ?</strong> Split() retourne alors un tableau ayant qu&rsquo;un seul indice égal à 0, donc pas de problème.<br />
<strong>Que se passe t&rsquo;il si le texte est vide Texte=&nbsp;&raquo;&nbsp;&raquo; ?</strong> Dans ce cas, Split() retourne un tableau particulier avec un indice le plus grand égal à <strong>-1</strong> qui est inférieur à l&rsquo;indice le plus petit du tableau (LBound() = 0)&#8230; C&rsquo;est pour cette raison que l&rsquo;on teste si &lsquo;Texte&rsquo; est différent d&rsquo;une chaîne vide (If Texte &lt;&gt; vbNullString Then &#8230;). Dans ce cas la fonction retournera 0.</p>
<p>On remarquera que Texte et Chaine sont de type String, la fonction n&rsquo;appréciera donc pas une valeur NULL&#8230; Lorsque le cas peut se présenter, je passe en paramètre Texte &amp; &laquo;&nbsp;&nbsp;&raquo; et le problème du NULL est réglé ! Pas très beau pour les puristes mais efficace. Une autre solution serait de définir Texte et Chaine en tant que Variant et de vérifier s&rsquo;ils sont différents de NULL ou bien encore, utiliser la fonction Nz() pour convertir les NULL en texte.</p>
<p>La requête SQL est dans ce cas :</p>
<div class="codecolorer-container sql blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">PARAMETERS <span style="color: #66cc66;">&#91;</span>Texte Recherché<span style="color: #66cc66;">&#93;</span> Text <span style="color: #66cc66;">&#40;</span> <span style="color: #cc66cc;">255</span> <span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">&#91;</span><span style="color: #993333; font-weight: bold;">TYPE</span> Comparaison <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #66cc66;">=</span>Binaire<span style="color: #66cc66;">/</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">=</span>Texte<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span> Byte;<br />
<span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">&#91;</span>Texte Recherché<span style="color: #66cc66;">&#93;</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #66cc66;">&#91;</span>Texte Cherché<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">,</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp;CompteOccurrences<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#91;</span>texte<span style="color: #66cc66;">&#93;</span> &amp; <span style="color: #ff0000;">&quot;&quot;</span><span style="color: #66cc66;">,</span><span style="color: #66cc66;">&#91;</span>Texte Recherché<span style="color: #66cc66;">&#93;</span> &amp; <span style="color: #ff0000;">&quot;&quot;</span><span style="color: #66cc66;">,</span><span style="color: #66cc66;">&#91;</span><span style="color: #993333; font-weight: bold;">TYPE</span> Comparaison <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #66cc66;">=</span>Binaire<span style="color: #66cc66;">/</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">=</span>Texte<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> Compte<span style="color: #66cc66;">,</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp;Texte<br />
<span style="color: #993333; font-weight: bold;">FROM</span> tOccurrence<br />
<span style="color: #993333; font-weight: bold;">WHERE</span> CompteOccurrences<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#91;</span>texte<span style="color: #66cc66;">&#93;</span> &amp; <span style="color: #ff0000;">&quot;&quot;</span><span style="color: #66cc66;">,</span><span style="color: #66cc66;">&#91;</span>Texte Recherché<span style="color: #66cc66;">&#93;</span> &amp; <span style="color: #ff0000;">&quot;&quot;</span><span style="color: #66cc66;">,</span><span style="color: #66cc66;">&#91;</span><span style="color: #993333; font-weight: bold;">TYPE</span> Comparaison <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #66cc66;">=</span>Binaire<span style="color: #66cc66;">/</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">=</span>Texte<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&gt;</span><span style="color: #cc66cc;">0</span><br />
<span style="color: #993333; font-weight: bold;">ORDER</span> <span style="color: #993333; font-weight: bold;">BY</span> CompteOccurrences<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#91;</span>texte<span style="color: #66cc66;">&#93;</span> &amp; <span style="color: #ff0000;">&quot;&quot;</span><span style="color: #66cc66;">,</span><span style="color: #66cc66;">&#91;</span>Texte Recherché<span style="color: #66cc66;">&#93;</span> &amp; <span style="color: #ff0000;">&quot;&quot;</span><span style="color: #66cc66;">,</span><span style="color: #66cc66;">&#91;</span><span style="color: #993333; font-weight: bold;">TYPE</span> Comparaison <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #66cc66;">=</span>Binaire<span style="color: #66cc66;">/</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">=</span>Texte<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">DESC</span>;</div></div>
<p>La requête a deux paramètres : Le texte recherché et le type de comparaison de texte (0 ou 1).<br />
La clause WHERE permet de ne retourner que les textes qui possèdent au moins une occurrence et ORDER BY tri les résultats par ordre décroissant du nombre d&rsquo;occurrences.</p>
<p><strong>La technique directe dans le SQL</strong><br />
On utilise bien sûr des fonctions VBA mais elles sont appelées directement dans la requête.<br />
Par contre, On n&rsquo;utilise plus Split() et Ubound() car elles ne peuvent pas être appelées directement du SQL.</p>
<p>La technique retenue consiste à remplacer dans le Texte chaque occurrence de la chaine recherchée par une chaine vide. En connaissant aussi la longueur initiale du Texte et la longueur de la chaine recherchée on peut facilement déterminer le compte des occurrences.<br />
Reprenons notre exemple &lsquo;A-B-C&rsquo;. La longueur initiale est 5, la longueur de la chaîne recherchée est 1 (&lsquo;-&lsquo;) et la longueur du texte après avoir retiré les chaînes recherchées est 3 (&lsquo;ABC&rsquo;)<br />
Donc (5 &#8211; 3) / 1 = 2 occurrences.<br />
On utilise la fonction Len() pour déterminer la longueur des chaînes de caractères et la fonction Replace() pour remplacer les chaînes recherchées par une chaîne vide et pour gérer le type de comparaison (binaire ou texte).</p>
<p>La requête est :</p>
<div class="codecolorer-container sql blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">PARAMETERS <span style="color: #66cc66;">&#91;</span>Texte Recherché<span style="color: #66cc66;">&#93;</span> Text <span style="color: #66cc66;">&#40;</span> <span style="color: #cc66cc;">255</span> <span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">&#91;</span><span style="color: #993333; font-weight: bold;">TYPE</span> Comparaison <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #66cc66;">=</span>Binaire<span style="color: #66cc66;">/</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">=</span>Texte<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span> Byte;<br />
<span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">&#91;</span>Texte Recherché<span style="color: #66cc66;">&#93;</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #66cc66;">&#91;</span>Texte Cherché<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">,</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">&#40;</span>Len<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#91;</span>Texte<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">-</span>Len<span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">REPLACE</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#91;</span>texte<span style="color: #66cc66;">&#93;</span> &amp; <span style="color: #ff0000;">&quot;&quot;</span><span style="color: #66cc66;">,</span><span style="color: #66cc66;">&#91;</span>Texte Recherché<span style="color: #66cc66;">&#93;</span> &amp; <span style="color: #ff0000;">&quot;&quot;</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">&quot;&quot;</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,-</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,</span><span style="color: #66cc66;">&#91;</span><span style="color: #993333; font-weight: bold;">TYPE</span> Comparaison <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #66cc66;">=</span>Binaire<span style="color: #66cc66;">/</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">=</span>Texte<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">/</span>Len<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#91;</span>Texte Recherché<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> Compte<span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; Texte<br />
<span style="color: #993333; font-weight: bold;">FROM</span> tOccurrence<br />
<span style="color: #993333; font-weight: bold;">WHERE</span> <span style="color: #66cc66;">&#40;</span>Len<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#91;</span>Texte<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">-</span>Len<span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">REPLACE</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#91;</span>texte<span style="color: #66cc66;">&#93;</span> &amp; <span style="color: #ff0000;">&quot;&quot;</span><span style="color: #66cc66;">,</span><span style="color: #66cc66;">&#91;</span>Texte Recherché<span style="color: #66cc66;">&#93;</span> &amp; <span style="color: #ff0000;">&quot;&quot;</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">&quot;&quot;</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,-</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,</span><span style="color: #66cc66;">&#91;</span><span style="color: #993333; font-weight: bold;">TYPE</span> Comparaison <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #66cc66;">=</span>Binaire<span style="color: #66cc66;">/</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">=</span>Texte<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">/</span>Len<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#91;</span>Texte Recherché<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&gt;</span><span style="color: #cc66cc;">0</span><br />
<span style="color: #993333; font-weight: bold;">ORDER</span> <span style="color: #993333; font-weight: bold;">BY</span> <span style="color: #66cc66;">&#40;</span>Len<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#91;</span>Texte<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">-</span>Len<span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">REPLACE</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#91;</span>texte<span style="color: #66cc66;">&#93;</span> &amp; <span style="color: #ff0000;">&quot;&quot;</span><span style="color: #66cc66;">,</span><span style="color: #66cc66;">&#91;</span>Texte Recherché<span style="color: #66cc66;">&#93;</span> &amp; <span style="color: #ff0000;">&quot;&quot;</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">&quot;&quot;</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,-</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,</span><span style="color: #66cc66;">&#91;</span><span style="color: #993333; font-weight: bold;">TYPE</span> Comparaison <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #66cc66;">=</span>Binaire<span style="color: #66cc66;">/</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">=</span>Texte<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">/</span>Len<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#91;</span>Texte Recherché<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">DESC</span>;</div></div>
<p>On remarquera que l&rsquo;on passe [Texte] &amp; &laquo;&nbsp;&nbsp;&raquo; à la fonction Replace() pour éviter le problème des valeurs NULL (même chose pour le texte recherché).</p>
<p><strong>Utilisation des requêtes</strong><br />
La requête exige deux paramètres. Le texte recherché doit contenir au moins un caractère et le type de comparaison (0 pour binaire ou 1 pour texte).</p>
<p><strong>Performance</strong><br />
Pour comparer la performance des deux méthodes, il est nécessaire tout d&rsquo;abord de fermer l&rsquo;application Access puis de la réouvrir pour que la requête avec la fonction VBA soit performante.</p>
<p>@+</p>
<p>Philippe</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Extraire les anniversaires sur une période de l&#8217;année</title>
		<link>https://blog.developpez.com/philben/p11064/sql-access/extraire_les_anniversaires_sur_une_periode</link>
		<comments>https://blog.developpez.com/philben/p11064/sql-access/extraire_les_anniversaires_sur_une_periode#comments</comments>
		<pubDate>Sat, 02 Jun 2012 14:01:13 +0000</pubDate>
		<dc:creator><![CDATA[philben]]></dc:creator>
				<category><![CDATA[SQL - Ms Access]]></category>
		<category><![CDATA[Date]]></category>
		<category><![CDATA[Requête SQL]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Un internaute souhaitait une requête SQL paramétrée pour afficher l&#8217;Id et la date de naissance des animaux dont l&#8217;anniversaire tombe sur une période de l&#8217;année. Création de la table et insertion des données Public Function CreationTableNaissance() &#160; &#160;Const cInsert As &#8230; <a href="https://blog.developpez.com/philben/p11064/sql-access/extraire_les_anniversaires_sur_une_periode">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Un internaute souhaitait une requête SQL paramétrée pour afficher l&rsquo;Id et la date de naissance des animaux dont <strong>l&rsquo;anniversaire</strong> tombe sur une période de l&rsquo;année.<br />
<span id="more-27"></span><br />
<strong>Création de la table et insertion des données</strong></p>
<div class="codecolorer-container vb blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="vb codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #E56717; font-weight: bold;">Public</span> <span style="color: #E56717; font-weight: bold;">Function</span> CreationTableNaissance() <br />
&nbsp; &nbsp;Const cInsert <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span> = <span style="color: #800000;">&quot;INSERT INTO tNaissance (DateNaissance) VALUES &quot;</span> <br />
&nbsp;<br />
&nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">With</span> DoCmd <br />
&nbsp; &nbsp; &nbsp; .SetWarnings <span style="color: #00C2FF; font-weight: bold;">False</span> <br />
&nbsp;<br />
&nbsp; &nbsp; &nbsp; .RunSQL <span style="color: #800000;">&quot;CREATE TABLE tNaissance (Id AUTOINCREMENT CONSTRAINT PrimaryKey PRIMARY KEY, DateNaissance DATE);&quot;</span> <br />
&nbsp;<br />
&nbsp; &nbsp; &nbsp; .RunSQL cInsert &amp; <span style="color: #800000;">&quot;(#1/1/2011#);&quot;</span> <br />
&nbsp; &nbsp; &nbsp; .RunSQL cInsert &amp; <span style="color: #800000;">&quot;(#15/12/2010#);&quot;</span> <br />
&nbsp; &nbsp; &nbsp; .RunSQL cInsert &amp; <span style="color: #800000;">&quot;(#05/07/2009#);&quot;</span> <br />
&nbsp; &nbsp; &nbsp; .RunSQL cInsert &amp; <span style="color: #800000;">&quot;(#29/02/2008#);&quot;</span> <br />
&nbsp; &nbsp; &nbsp; .RunSQL cInsert &amp; <span style="color: #800000;">&quot;(#26/10/2008#);&quot;</span> <br />
&nbsp; &nbsp; &nbsp; .RunSQL cInsert &amp; <span style="color: #800000;">&quot;(#11/01/2009#);&quot;</span> <br />
&nbsp; &nbsp; &nbsp; .RunSQL cInsert &amp; <span style="color: #800000;">&quot;(NULL);&quot;</span> <br />
&nbsp;<br />
&nbsp; &nbsp; &nbsp; .SetWarnings <span style="color: #00C2FF; font-weight: bold;">True</span> <br />
&nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">With</span> <br />
&nbsp; &nbsp;MsgBox <span style="color: #800000;">&quot;Création terminée&quot;</span> <br />
<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #E56717; font-weight: bold;">Function</span></div></div>
<p><strong>Analyse du problème</strong><br />
A priori, la requête semble aisée : Il suffit d&rsquo;extraire les dates de naissance dont le mois et le jour sont dans la période de l&rsquo;année définie.<br />
<strong>Exemple pour la période entre le 15/05 et le 10/07</strong> :<br />
Une erreur souvent commise est de filtrer indépendamment les mois et les jours des dates de naissance<br />
<code class="codecolorer sql blackboard"><span class="sql"><span style="color: #66cc66;">...</span> <span style="color: #993333; font-weight: bold;">WHERE</span> <span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#91;</span>DateNaissance<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">BETWEEN</span> <span style="color: #cc66cc;">5</span> <span style="color: #993333; font-weight: bold;">AND</span> <span style="color: #cc66cc;">7</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AND</span> <span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#91;</span>DateNaissance<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">BETWEEN</span> <span style="color: #cc66cc;">10</span> <span style="color: #993333; font-weight: bold;">AND</span> <span style="color: #cc66cc;">15</span><span style="color: #66cc66;">&#41;</span></span></code><br />
On obtient <strong>que</strong> les dates de naissance entre le 10 et le 15 des mois de mai, juin et juillet ce qui n&rsquo;est pas l&rsquo;objectif recherché.</p>
<p>Pour récupérer toutes les dates sur cette période on peut écrire en condition de filtre de la requête :<br />
<code class="codecolorer sql blackboard"><span class="sql"><span style="color: #66cc66;">...</span><span style="color: #993333; font-weight: bold;">WHERE</span> <span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#91;</span>DateNaissance<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">*</span><span style="color: #cc66cc;">100</span><span style="color: #66cc66;">+</span><span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#91;</span>DateNaissance<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">BETWEEN</span> <span style="color: #cc66cc;">515</span> <span style="color: #993333; font-weight: bold;">AND</span> <span style="color: #cc66cc;">710</span></span></code><br />
515 et 710 correspondent au [n° du mois] * 100 + [le jour du mois] de la période étudiée.</p>
<p><strong>Et voilà le tour est joué&#8230; mais pas complétement !</strong><br />
En effet, que se passe t&rsquo;il sur une période entre le 10/07 et le 15/05?<br />
<code class="codecolorer sql blackboard"><span class="sql"><span style="color: #66cc66;">...</span><span style="color: #993333; font-weight: bold;">WHERE</span> <span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#91;</span>DateNaissance<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">*</span><span style="color: #cc66cc;">100</span><span style="color: #66cc66;">+</span><span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#91;</span>DateNaissance<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">BETWEEN</span> <span style="color: #cc66cc;">710</span> <span style="color: #993333; font-weight: bold;">AND</span> <span style="color: #cc66cc;">515</span></span></code><br />
Access retourne toutes les dates de naissances entre 515 et 710 soit exactement l&rsquo;inverse de ce que l&rsquo;on souhaite mis à part nos deux bornes.</p>
<p><strong>Une solution universelle</strong><br />
Graphiquement, la période du 10/07 au 15/05 est</p>
<div class="codecolorer-container text geshi" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; &nbsp; &nbsp;/<br />
&nbsp; &nbsp; &nbsp; &nbsp;| Début période : 10/07<br />
&nbsp; &nbsp; &nbsp; &nbsp;|<br />
&nbsp; &nbsp; &nbsp; &nbsp;|<br />
&nbsp;01/01 |<br />
&nbsp; &nbsp; &nbsp; &nbsp;|<br />
&nbsp; &nbsp; &nbsp; &nbsp;|<br />
&nbsp; &nbsp; &nbsp; &nbsp;| Fin période : 15/05<br />
&nbsp; &nbsp; &nbsp; &nbsp;/</div></div>
<p>Ce qui est équivalent sur l&rsquo;échelle d&rsquo;une année :</p>
<div class="codecolorer-container text geshi" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp;01/01 |<br />
&nbsp; &nbsp; &nbsp; &nbsp;|<br />
&nbsp; &nbsp; &nbsp; &nbsp;| Fin période : 15/05<br />
&nbsp; &nbsp; &nbsp; &nbsp;/<br />
&nbsp; &nbsp; &nbsp; &nbsp;/<br />
&nbsp; &nbsp; &nbsp; &nbsp;| Début période : 10/07<br />
&nbsp; &nbsp; &nbsp; &nbsp;|<br />
&nbsp;31/12 |</div></div>
<p>A l&rsquo;échelle d&rsquo;une année, on remarque que la date de fin période est antérieure à la date de début de période lorsque la période s&rsquo;étale sur &lsquo;deux années&rsquo;<br />
En résumé, si D:MMJJ du début de période est plus grand que F:MMJJ de fin de période il suffit d&rsquo;écrire la clause WHERE suivante :<br />
<code class="codecolorer sql blackboard"><span class="sql"><span style="color: #66cc66;">...</span><span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#91;</span>DateNaissance<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">*</span><span style="color: #cc66cc;">100</span><span style="color: #66cc66;">+</span><span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#91;</span>DateNaissance<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">BETWEEN</span> <span style="color: #cc66cc;">515</span> <span style="color: #66cc66;">+</span> <span style="color: #cc66cc;">1</span> <span style="color: #993333; font-weight: bold;">AND</span> <span style="color: #cc66cc;">710</span> <span style="color: #66cc66;">-</span> <span style="color: #cc66cc;">1</span></span></code><br />
On obtient donc toutes les dates qui <strong>ne sont pas entre le 16/05 et le 09/07</strong></p>
<p><strong>Finalement</strong>, si Début période &lt;= à Fin période alors on veut les dates entre Début et Fin sinon on veut les dates qui ne sont pas entre Fin + 1 et Début &#8211; 1.</p>
<p><strong>La requête paramétrée</strong></p>
<div class="codecolorer-container sql blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">PARAMETERS <span style="color: #66cc66;">&#91;</span>Debut Periode <span style="color: #66cc66;">&#40;</span>MMJJ<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span> LONG<span style="color: #66cc66;">,</span> <span style="color: #66cc66;">&#91;</span>Fin Periode <span style="color: #66cc66;">&#40;</span>MMJJ<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span> LONG;<br />
<br />
<span style="color: #993333; font-weight: bold;">SELECT</span> tnaissance<span style="color: #66cc66;">.</span>id<span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;tnaissance<span style="color: #66cc66;">.</span>datenaissance<br />
<span style="color: #993333; font-weight: bold;">FROM</span> &nbsp; tnaissance<br />
<span style="color: #993333; font-weight: bold;">WHERE</span> &nbsp;<span style="color: #66cc66;">&#40;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">&#91;</span>debut periode <span style="color: #66cc66;">&#40;</span>mmjj<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span> &nbsp;<span style="color: #66cc66;">&lt;=</span> <span style="color: #66cc66;">&#91;</span>fin periode <span style="color: #66cc66;">&#40;</span>mmjj<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">AND</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#91;</span>datenaissance<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">100</span> <span style="color: #66cc66;">+</span> <span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#91;</span>datenaissance<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">BETWEEN</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">&#91;</span>debut periode <span style="color: #66cc66;">&#40;</span>mmjj<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span> <span style="color: #993333; font-weight: bold;">AND</span> <span style="color: #66cc66;">&#91;</span>fin periode <span style="color: #66cc66;">&#40;</span>mmjj<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span> &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">OR</span> <span style="color: #66cc66;">&#40;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">&#91;</span>debut periode <span style="color: #66cc66;">&#40;</span>mmjj<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span> &nbsp;<span style="color: #66cc66;">&gt;</span> <span style="color: #66cc66;">&#91;</span>fin periode <span style="color: #66cc66;">&#40;</span>mmjj<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">AND</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#91;</span>datenaissance<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">100</span> <span style="color: #66cc66;">+</span> <span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#91;</span>datenaissance<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> &nbsp;<span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">BETWEEN</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">&#91;</span>fin periode <span style="color: #66cc66;">&#40;</span>mmjj<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">+</span> <span style="color: #cc66cc;">1</span> <span style="color: #993333; font-weight: bold;">AND</span> <span style="color: #66cc66;">&#91;</span>debut periode <span style="color: #66cc66;">&#40;</span>mmjj<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">-</span> <span style="color: #cc66cc;">1</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">&#41;</span><br />
<span style="color: #993333; font-weight: bold;">ORDER</span> &nbsp;<span style="color: #993333; font-weight: bold;">BY</span> tnaissance<span style="color: #66cc66;">.</span>datenaissance;</div></div>
<p>Lorsque la requete demande les paramètres, écrire <strong>515</strong> pour le 15 mai et <strong>710</strong> pour le 10 juillet.</p>
<p><strong>Autres requêtes paramétrées sur les anniversaires</strong><br />
On souhaite une requete qui nous retourne les dates de naissance dans x jours et sur une période de y jours.<br />
Potentiellement, on peut regretter que la solution précédente teste deux fois le début période par rapport à la fin de période :<br />
<code class="codecolorer sql blackboard"><span class="sql"><span style="color: #66cc66;">&#40;</span>Si debut <span style="color: #66cc66;">&lt;=</span> fin Et <span style="color: #66cc66;">...</span> <span style="color: #66cc66;">&#41;</span> OU <span style="color: #66cc66;">&#40;</span>Si debut <span style="color: #66cc66;">&gt;</span> fin Et <span style="color: #66cc66;">...</span><span style="color: #66cc66;">&#41;</span></span></code><br />
Pour ne tester qu&rsquo;une fois, on peut s&rsquo;appuyer sur la fonction IIF() de VBA qui correspond à Si,alors,sinon.</p>
<p>De plus la formule avec <code class="codecolorer sql blackboard"><span class="sql"><span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>x100 <span style="color: #66cc66;">+</span> <span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span></span></code> pourrait être simplifieé en utilisant la fonction format(Date,&rsquo;mmdd&rsquo;). Il faut utiliser &laquo;&nbsp;mmdd&nbsp;&raquo; et non &laquo;&nbsp;mdd&nbsp;&raquo; car la fonction format retourne un string et non un numérique et &lsquo;<strong>0</strong>515&prime; (15 mai) est bien &lt; &lsquo;1015&rsquo; (15 octobre) mais &lsquo;515&rsquo; est &gt; &lsquo;1015&rsquo; !</p>
<p>Voici la requête avec IIf() seulement :</p>
<div class="codecolorer-container sql blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">PARAMETERS <span style="color: #66cc66;">&#91;</span>Dans x Jours<span style="color: #66cc66;">&#93;</span> SHORT<span style="color: #66cc66;">,</span> <span style="color: #66cc66;">&#91;</span>Sur y Jours<span style="color: #66cc66;">&#93;</span> SHORT;<br />
<br />
<span style="color: #993333; font-weight: bold;">SELECT</span> &nbsp; &nbsp; &nbsp;tnaissance<span style="color: #66cc66;">.</span>id<span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tnaissance<span style="color: #66cc66;">.</span>datenaissance<span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">DATE</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">+</span> <span style="color: #66cc66;">&#91;</span>dans x jours<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">100</span> <span style="color: #66cc66;">+</span> <span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">DATE</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">+</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#91;</span>dans x jours<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #66cc66;">&#91;</span>Début période<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">DATE</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">+</span> <span style="color: #66cc66;">&#91;</span>dans x jours<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">+</span> <span style="color: #66cc66;">&#91;</span>sur y jours<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">-</span> <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">100</span> <span style="color: #66cc66;">+</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">DATE</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">+</span> <span style="color: #66cc66;">&#91;</span>dans x jours<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">+</span> <span style="color: #66cc66;">&#91;</span>sur y jours<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">-</span> <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #66cc66;">&#91;</span>Fin période<span style="color: #66cc66;">&#93;</span><br />
<span style="color: #993333; font-weight: bold;">FROM</span> &nbsp; &nbsp; &nbsp; &nbsp;tnaissance<br />
<span style="color: #993333; font-weight: bold;">WHERE</span> &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#40;</span> &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#40;</span> Iif<span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">DATE</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">+</span> <span style="color: #66cc66;">&#91;</span>dans x jours<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">100</span> <span style="color: #66cc66;">+</span> <span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">DATE</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">+</span> <span style="color: #66cc66;">&#91;</span>dans x jours<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&lt;=</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">DATE</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">+</span> <span style="color: #66cc66;">&#91;</span>dans x jours<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">+</span> <span style="color: #66cc66;">&#91;</span>sur y jours<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">-</span> <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">100</span> <span style="color: #66cc66;">+</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">DATE</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">+</span> <span style="color: #66cc66;">&#91;</span>dans x jours<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">+</span> <span style="color: #66cc66;">&#91;</span>sur y jours<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">-</span> <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#91;</span>datenaissance<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">100</span> <span style="color: #66cc66;">+</span> <span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#91;</span>datenaissance<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">BETWEEN</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">DATE</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">+</span> <span style="color: #66cc66;">&#91;</span>dans x jours<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">100</span> <span style="color: #66cc66;">+</span> <span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">DATE</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">+</span> <span style="color: #66cc66;">&#91;</span>dans x jours<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">AND</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">DATE</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">+</span> <span style="color: #66cc66;">&#91;</span>dans x jours<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">+</span> <span style="color: #66cc66;">&#91;</span>sur y jours<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">-</span> <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">100</span> <span style="color: #66cc66;">+</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">DATE</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">+</span> <span style="color: #66cc66;">&#91;</span>dans x jours<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">+</span> <span style="color: #66cc66;">&#91;</span>sur y jours<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">-</span> <span style="color: #cc66cc;">1</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#91;</span>datenaissance<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">100</span> <span style="color: #66cc66;">+</span> <span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#91;</span>datenaissance<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">BETWEEN</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">DATE</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">+</span> <span style="color: #66cc66;">&#91;</span>dans x jours<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">+</span> <span style="color: #66cc66;">&#91;</span>sur y jours<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">100</span> <span style="color: #66cc66;">+</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">DATE</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">+</span> <span style="color: #66cc66;">&#91;</span>dans x jours<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">+</span> <span style="color: #66cc66;">&#91;</span>sur y jours<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">AND</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">DATE</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">+</span> <span style="color: #66cc66;">&#91;</span>dans x jours<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">100</span> <span style="color: #66cc66;">+</span> <span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">DATE</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">+</span> <span style="color: #66cc66;">&#91;</span>dans x jours<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">-</span> <span style="color: #cc66cc;">1</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">&#41;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&lt;&gt;</span> <span style="color: #993333; font-weight: bold;">FALSE</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#41;</span><br />
<span style="color: #993333; font-weight: bold;">ORDER</span> <span style="color: #993333; font-weight: bold;">BY</span> tnaissance<span style="color: #66cc66;">.</span>datenaissance;</div></div>
<p>Et la requête avec IIF() et Format() :</p>
<div class="codecolorer-container sql blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">PARAMETERS &nbsp;<span style="color: #66cc66;">&#91;</span>Dans x Jours<span style="color: #66cc66;">&#93;</span> SHORT<span style="color: #66cc66;">,</span> <span style="color: #66cc66;">&#91;</span>Sur y Jours<span style="color: #66cc66;">&#93;</span> SHORT;<br />
&nbsp;<br />
<span style="color: #993333; font-weight: bold;">SELECT</span> &nbsp; &nbsp; &nbsp;tnaissance<span style="color: #66cc66;">.</span>id<span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tnaissance<span style="color: #66cc66;">.</span>datenaissance<span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Format<span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">DATE</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">+</span> <span style="color: #66cc66;">&#91;</span>dans x jours<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">&quot;mmdd&quot;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #66cc66;">&#91;</span>Début période<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Format<span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">DATE</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">+</span> <span style="color: #66cc66;">&#91;</span>dans x jours<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">+</span> <span style="color: #66cc66;">&#91;</span>sur y jours<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">-</span> <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">&quot;mmdd&quot;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #66cc66;">&#91;</span>Fin période<span style="color: #66cc66;">&#93;</span><br />
<span style="color: #993333; font-weight: bold;">FROM</span> &nbsp; &nbsp; &nbsp; &nbsp;tnaissance<br />
<span style="color: #993333; font-weight: bold;">WHERE</span> &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#40;</span> Iif<span style="color: #66cc66;">&#40;</span>Format<span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">DATE</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">+</span> <span style="color: #66cc66;">&#91;</span>dans x jours<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">&quot;mmdd&quot;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&lt;=</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Format<span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">DATE</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">+</span> <span style="color: #66cc66;">&#91;</span>dans x jours<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">+</span> <span style="color: #66cc66;">&#91;</span>sur y jours<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">-</span> <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">&quot;mmdd&quot;</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Format<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#91;</span>datenaissance<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">&quot;mmdd&quot;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">BETWEEN</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Format<span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">DATE</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">+</span> <span style="color: #66cc66;">&#91;</span>dans x jours<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">&quot;mmdd&quot;</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">AND</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Format<span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">DATE</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">+</span> <span style="color: #66cc66;">&#91;</span>dans x jours<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">+</span> <span style="color: #66cc66;">&#91;</span>sur y jours<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">-</span> <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">&quot;mmdd&quot;</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">,</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Format<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#91;</span>datenaissance<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">&quot;mmdd&quot;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">BETWEEN</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Format<span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">DATE</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">+</span> <span style="color: #66cc66;">&#91;</span>dans x jours<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">+</span> <span style="color: #66cc66;">&#91;</span>sur y jours<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">&quot;mmdd&quot;</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">AND</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Format<span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">DATE</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">+</span> <span style="color: #66cc66;">&#91;</span>dans x jours<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">-</span> <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">&quot;mmdd&quot;</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#41;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">=</span> <span style="color: #993333; font-weight: bold;">TRUE</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#41;</span><br />
<span style="color: #993333; font-weight: bold;">ORDER</span> <span style="color: #993333; font-weight: bold;">BY</span> &nbsp; &nbsp;tnaissance<span style="color: #66cc66;">.</span>datenaissance;</div></div>
<p><strong>Remarques</strong><br />
La période s&rsquo;étale du jour <strong>Date() + X</strong> à <strong>Date() + X + Y &#8211; 1</strong> car on inclut les bornes et on limite la longueur de la période à seulement Y jours.</p>
<p>Donc, &lsquo;Dans x jours&rsquo; doit être &gt;= à 0 et &lsquo;Sur y jours&rsquo; doit être &gt;= à 1</p>
<p>On remarquera que si une date de naissance est NULL, la deuxième requête avec Format() la retourne si la période passe par le 1er janvier (car une chaine vide <strong>n&rsquo;est pas </strong>dans la période entre &laquo;&nbsp;F:mmdd&nbsp;&raquo; et &laquo;&nbsp;D:mmdd&nbsp;&raquo;). On peut s&rsquo;affranchir de cet artefact en ajoutant dans la clause where une condition supplémentaire qui écarte les dates de naissance NULL.</p>
<p><strong>Performance</strong><br />
La performance des différentes requêtes est excellente.<br />
Pour la tester, voici une fonction qui ajoute 100 000 lignes à la table :</p>
<div class="codecolorer-container vb blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="vb codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #E56717; font-weight: bold;">Public</span> <span style="color: #E56717; font-weight: bold;">Function</span> GenereNaissances() <br />
&nbsp; &nbsp;Const clMaxNaissances <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Long</span> = 100000 <br />
&nbsp; &nbsp;<span style="color: #151B8D; font-weight: bold;">Dim</span> odb <span style="color: #151B8D; font-weight: bold;">As</span> DAO.Database <br />
&nbsp; &nbsp;<span style="color: #151B8D; font-weight: bold;">Dim</span> ors <span style="color: #151B8D; font-weight: bold;">As</span> DAO.Recordset <br />
&nbsp; &nbsp;<span style="color: #151B8D; font-weight: bold;">Dim</span> i <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Long</span> <br />
&nbsp;<br />
&nbsp; &nbsp;<span style="color: #151B8D; font-weight: bold;">Set</span> odb = CurrentDb <br />
&nbsp; &nbsp;<span style="color: #151B8D; font-weight: bold;">Set</span> ors = odb.OpenRecordset(<span style="color: #800000;">&quot;tNaissance&quot;</span>, dbOpenDynaset) <br />
&nbsp; &nbsp;Randomize <br />
&nbsp;<br />
&nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">With</span> ors <br />
&nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">For</span> i = 1 <span style="color: #8D38C9; font-weight: bold;">To</span> clMaxNaissances <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.AddNew <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;!DateNaissance = DateAdd(<span style="color: #800000;">&quot;d&quot;</span>, Int((#1/1/2012# - #1/1/1900# + 1) * Rnd()), #1/1/1900#) <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.Update <br />
&nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">Next</span> i <br />
&nbsp; &nbsp; &nbsp; .<span style="color: #8D38C9; font-weight: bold;">Close</span> <br />
&nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">With</span> <br />
&nbsp;<br />
&nbsp; &nbsp;<span style="color: #151B8D; font-weight: bold;">Set</span> ors = <span style="color: #00C2FF; font-weight: bold;">Nothing</span> <br />
&nbsp; &nbsp;<span style="color: #151B8D; font-weight: bold;">Set</span> odb = <span style="color: #00C2FF; font-weight: bold;">Nothing</span> <br />
&nbsp; &nbsp;MsgBox clMaxNaissances &amp; <span style="color: #800000;">&quot; naissance(s) générée(s)&quot;</span> <br />
<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #E56717; font-weight: bold;">Function</span></div></div>
<p>Bon anniversaire !</p>
<p>Philippe</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Top 11 à 15 avec regroupement</title>
		<link>https://blog.developpez.com/philben/p11052/sql-access/top_11_a_15_avec_regroupement</link>
		<comments>https://blog.developpez.com/philben/p11052/sql-access/top_11_a_15_avec_regroupement#comments</comments>
		<pubDate>Mon, 28 May 2012 15:19:14 +0000</pubDate>
		<dc:creator><![CDATA[philben]]></dc:creator>
				<category><![CDATA[SQL - Ms Access]]></category>
		<category><![CDATA[Requête SQL]]></category>
		<category><![CDATA[Top]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Suite au billet précédent, on souhaite obtenir le TOP 11 à 15 des Id (par ordre croissant) liés à chaque personne. Création de la table et insertion des données La structure de la table est un peu différente du billet &#8230; <a href="https://blog.developpez.com/philben/p11052/sql-access/top_11_a_15_avec_regroupement">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Suite au <a href="http://blog.developpez.com/philben/p11047/sql/top-3-aleatoire-avec-regroupement/">billet précédent</a>, on souhaite obtenir le TOP 11 à 15 des Id (par ordre croissant) liés à chaque personne.<br />
<span id="more-26"></span><br />
<strong>Création de la table et insertion des données</strong><br />
La structure de la table est un peu différente du billet précédent pour visualiser facilement la sélection de la requête :</p>
<div class="codecolorer-container vb blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="vb codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #E56717; font-weight: bold;">Public</span> <span style="color: #E56717; font-weight: bold;">Function</span> CreationTableTop2() <br />
&nbsp; &nbsp;Const cInsert <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span> = <span style="color: #800000;">&quot;INSERT INTO tTop2 (Id, Nom) VALUES &quot;</span> <br />
&nbsp; &nbsp;<span style="color: #151B8D; font-weight: bold;">Dim</span> i <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Long</span>, j <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Long</span> <br />
&nbsp; &nbsp;<span style="color: #151B8D; font-weight: bold;">Dim</span> aNoms <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Variant</span> <br />
&nbsp;<br />
&nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">With</span> DoCmd <br />
&nbsp; &nbsp; &nbsp; .SetWarnings <span style="color: #00C2FF; font-weight: bold;">False</span> <br />
&nbsp;<br />
&nbsp; &nbsp; &nbsp; .RunSQL <span style="color: #800000;">&quot;CREATE TABLE tTop2 (Id LONG, Nom CHAR, &quot;</span> &amp; _ <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #800000;">&quot;CONSTRAINT PrimaryKey PRIMARY KEY(Id, Nom));&quot;</span> <br />
&nbsp;<br />
&nbsp; &nbsp; &nbsp; aNoms = Array(<span style="color: #800000;">&quot;Albert&quot;</span>, <span style="color: #800000;">&quot;Marcel&quot;</span>, <span style="color: #800000;">&quot;Bernard&quot;</span>, <span style="color: #800000;">&quot;Dominique&quot;</span>) <br />
&nbsp;<br />
&nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">For</span> i = <span style="color: #151B8D; font-weight: bold;">LBound</span>(aNoms) <span style="color: #8D38C9; font-weight: bold;">To</span> <span style="color: #151B8D; font-weight: bold;">UBound</span>(aNoms) <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">For</span> j = 1 <span style="color: #8D38C9; font-weight: bold;">To</span> 25 <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .RunSQL cInsert &amp; <span style="color: #800000;">&quot;(&quot;</span> &amp; j &amp; <span style="color: #800000;">&quot;,'&quot;</span> &amp; aNoms(i) &amp; <span style="color: #800000;">&quot;');&quot;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">Next</span> j <br />
&nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">Next</span> i <br />
&nbsp;<br />
&nbsp; &nbsp; &nbsp; .SetWarnings <span style="color: #00C2FF; font-weight: bold;">True</span> <br />
&nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">With</span> <br />
&nbsp; &nbsp;MsgBox <span style="color: #800000;">&quot;Création terminée&quot;</span> <br />
<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #E56717; font-weight: bold;">Function</span></div></div>
<p>&nbsp;<br />
<strong>Résultat attendu</strong></p>
<blockquote><p>
Id	Nom<br />
11	Albert<br />
12	Albert<br />
13	Albert<br />
14	Albert<br />
15	Albert<br />
11	Bernard<br />
12	Bernard<br />
&#8230;
</p></blockquote>
<p>&nbsp;<br />
<strong>La requête SQL</strong><br />
Une solution possible est :</p>
<pre style="font-size: 12px;"><font color="black"><br /></font><font color="blue">SELECT </font><font color="gray">* <br /></font><font color="blue">FROM&nbsp;&nbsp; </font><font color="black">ttop2 </font><font color="blue">AS </font><font color="black">T1 <br /></font><font color="blue">WHERE&nbsp;&nbsp;</font><font color="black">id </font><font color="gray">&gt; ALL (</font><font color="blue">SELECT TOP </font><font color="black">10 id <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font color="blue">FROM&nbsp;&nbsp; </font><font color="black">ttop2 T <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font color="blue">WHERE&nbsp;&nbsp;</font><font color="black">T.nom </font><font color="blue">= </font><font color="black">T1.nom <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font color="blue">ORDER&nbsp;&nbsp;BY </font><font color="black">id</font><font color="gray">) <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AND </font><font color="black">id </font><font color="gray">&lt;= </font><font color="blue">ANY </font><font color="gray">(</font><font color="blue">SELECT TOP </font><font color="black">15 id <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="blue">FROM&nbsp;&nbsp; </font><font color="black">ttop2 T <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="blue">WHERE&nbsp;&nbsp;</font><font color="black">T.nom </font><font color="blue">= </font><font color="black">T1.nom <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="blue">ORDER&nbsp;&nbsp;BY </font><font color="black">id</font><font color="gray">) <br /></font><font color="blue">ORDER&nbsp;&nbsp;BY </font><font color="black">nom</font><font color="gray">, <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="black">id</font><font color="gray"><br /></font></pre>
<p>&nbsp;<br />
<strong>Explications</strong><br />
La clause Where va filtrer les lignes sur deux critères complémentaires :<br />
Toutes les lignes retournées doivent avoir un Id &gt; à <strong>tous</strong> les Id du TOP 10 du même NOM <strong>ET</strong> un Id &lt;= à <strong>au moins un</strong> Id du TOP 15 du même NOM.<br />
Finalement, seules les Id du TOP 11 à 15 répondent aux deux critères et les lignes correspondantes sont retournées.</p>
<p><strong>Autre solution</strong><br />
Il est possible de substituer <strong>&gt;ALL</strong> et <strong>&lt;=Any</strong> par <strong>Not In</strong> et <strong>In</strong> :</p>
<pre style="font-size: 12px;"><font color="blue">SELECT </font><font color="gray">*<br />&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="blue">FROM </font><font color="black">tTop2 </font><font color="blue">AS </font><font color="black">T1<br />&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="blue">WHERE </font><font color="black">id </font><font color="gray">NOT </font><font color="blue">IN&nbsp;&nbsp;</font><font color="gray">(<br />&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="blue">SELECT TOP </font><font color="black">10 Id <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="blue">FROM </font><font color="black">tTop2 T <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="blue">WHERE </font><font color="black">T.Nom</font><font color="blue">=</font><font color="black">T1.Nom <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="blue">ORDER BY </font><font color="black">Id</font><font color="gray">) <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AND </font><font color="black">id </font><font color="blue">IN </font><font color="gray">(<br />&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="blue">SELECT TOP </font><font color="black">15 Id <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="blue">FROM </font><font color="black">tTop2 T <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="blue">WHERE </font><font color="black">T.Nom</font><font color="blue">=</font><font color="black">T1.Nom <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="blue">ORDER BY </font><font color="black">Id</font><font color="gray">)<br />&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="blue">ORDER BY </font><font color="black">Nom</font><font color="gray">, </font><font color="black">id</font><font color="gray">;<br />&nbsp;</font></pre>
<p><strong>Performance</strong><br />
Il est recommandé d&rsquo;indexer sans doublons la colonne &lsquo;Nom&rsquo; sur laquelle porte la clause <strong>Where</strong>.<br />
Compte-tenu de la présence de 2 sous-requêtes, cette requête est adaptée pour une table possédant moins de 1000 lignes&#8230;</p>
<p>Si vous avez d&rsquo;autres solutions, n&rsquo;hésitez pas à les placer en commentaire.</p>
<p>@+</p>
<p>Philippe</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TOP 3 aléatoire avec regroupement</title>
		<link>https://blog.developpez.com/philben/p11047/sql-access/top_3_aleatoire_avec_regroupement</link>
		<comments>https://blog.developpez.com/philben/p11047/sql-access/top_3_aleatoire_avec_regroupement#comments</comments>
		<pubDate>Sat, 26 May 2012 08:50:06 +0000</pubDate>
		<dc:creator><![CDATA[philben]]></dc:creator>
				<category><![CDATA[SQL - Ms Access]]></category>
		<category><![CDATA[Aléatoire]]></category>
		<category><![CDATA[Requête SQL]]></category>
		<category><![CDATA[Top]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Un internaute souhaitait extraire aléatoirement 3 Id d&#8217;une table pour chaque personne. C&#8217;est possible ! Création de la table et insertion des données La table tTop contient une colonne Id (clef primaire) et le nom de la personne Public Function &#8230; <a href="https://blog.developpez.com/philben/p11047/sql-access/top_3_aleatoire_avec_regroupement">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Un internaute souhaitait extraire aléatoirement 3 Id d&rsquo;une table pour chaque personne. C&rsquo;est possible !<br />
<span id="more-25"></span><br />
<strong>Création de la table et insertion des données</strong><br />
La table tTop contient une colonne Id (clef primaire) et le nom de la personne</p>
<div class="codecolorer-container vb blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="vb codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #E56717; font-weight: bold;">Public</span> <span style="color: #E56717; font-weight: bold;">Function</span> CreationTableTop() <br />
&nbsp; &nbsp;Const cInsert <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span> = <span style="color: #800000;">&quot;INSERT INTO tTop (Nom) VALUES &quot;</span> <br />
&nbsp; &nbsp;<span style="color: #151B8D; font-weight: bold;">Dim</span> i <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Long</span>, Maxi <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Long</span> <br />
&nbsp; &nbsp;<span style="color: #151B8D; font-weight: bold;">Dim</span> aNoms <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Variant</span> <br />
&nbsp;<br />
&nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">With</span> DoCmd <br />
&nbsp; &nbsp; &nbsp; .SetWarnings <span style="color: #00C2FF; font-weight: bold;">False</span> <br />
&nbsp;<br />
&nbsp; &nbsp; &nbsp; .RunSQL <span style="color: #800000;">&quot;CREATE TABLE tTop (Id AUTOINCREMENT CONSTRAINT PrimaryKey PRIMARY KEY, Nom CHAR);&quot;</span> <br />
&nbsp;<br />
&nbsp; &nbsp; &nbsp; <span style="color: #008000;">'VBA.Array impose que le tableau débute à l'indice 0 (Array de la librairie VBA) <br />
</span> &nbsp; &nbsp; &nbsp;<span style="color: #008000;">'Autre solution : OPTION BASE 0 en tête du module <br />
</span> &nbsp; &nbsp; &nbsp;aNoms = VBA.Array(<span style="color: #800000;">&quot;Albert&quot;</span>, <span style="color: #800000;">&quot;Marcel&quot;</span>, <span style="color: #800000;">&quot;Bernard&quot;</span>) <br />
&nbsp; &nbsp; &nbsp; Maxi = <span style="color: #151B8D; font-weight: bold;">UBound</span>(aNoms) + 1 <br />
&nbsp;<br />
&nbsp; &nbsp; &nbsp; Randomize <br />
&nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">For</span> i = 1 <span style="color: #8D38C9; font-weight: bold;">To</span> 50 <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.RunSQL cInsert &amp; <span style="color: #800000;">&quot;('&quot;</span> &amp; aNoms(Int(Rnd() * Maxi)) &amp; <span style="color: #800000;">&quot;');&quot;</span> <br />
&nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">Next</span> i <br />
&nbsp; &nbsp; &nbsp; .RunSQL cInsert &amp; <span style="color: #800000;">&quot;('Dominique');&quot;</span> <br />
&nbsp;<br />
&nbsp; &nbsp; &nbsp; .SetWarnings <span style="color: #00C2FF; font-weight: bold;">True</span> <br />
&nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">With</span> <br />
&nbsp; &nbsp;MsgBox <span style="color: #800000;">&quot;Création terminée&quot;</span> <br />
<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #E56717; font-weight: bold;">Function</span></div></div>
<p><strong>Difficultés</strong><br />
La première difficulté est d&rsquo;obtenir un top 3 pour chaque Nom. Une solution consiste à filtrer les enregistrements en imposant les Id par Nom grâce à une sous-requête corrélée (WHERE T.Nom=T1.Nom) dans la clause IN :</p>
<div class="codecolorer-container sql blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">SELECT</span> &nbsp;<span style="color: #66cc66;">*</span><br />
<span style="color: #993333; font-weight: bold;">FROM</span> &nbsp; &nbsp;tTop <span style="color: #993333; font-weight: bold;">AS</span> T1<br />
<span style="color: #993333; font-weight: bold;">WHERE</span> &nbsp; T1<span style="color: #66cc66;">.</span>Id <span style="color: #993333; font-weight: bold;">IN</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> TOP <span style="color: #cc66cc;">3</span> Id<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">FROM</span> &nbsp; tTop T<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">WHERE</span> &nbsp;T<span style="color: #66cc66;">.</span>Nom <span style="color: #66cc66;">=</span> T1<span style="color: #66cc66;">.</span>Nom<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">ORDER</span> <span style="color: #993333; font-weight: bold;">BY</span> T<span style="color: #66cc66;">.</span>Id<span style="color: #66cc66;">&#41;</span><br />
<span style="color: #993333; font-weight: bold;">ORDER</span> <span style="color: #993333; font-weight: bold;">BY</span> T1<span style="color: #66cc66;">.</span>Nom<span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;T1<span style="color: #66cc66;">.</span>Id;</div></div>
<p>Le problème du Top 3 par Nom étant résolu, le plus compliqué reste à faire&#8230; Comment obtenir aléatoirement des Id pour chaque Nom ?<br />
En effet, on souhaite suffisamment d&rsquo;aléatoire pour que la liste des Id différe d&rsquo;un appel à l&rsquo;autre de la requête mais pas trop non plus pour que la sous-requête sorte la même liste des Id pour chaque T1.Id.<br />
L&rsquo;idée de base est d&rsquo;utiliser la fonction RND(T.Id) dans la clause ORDER BY pour trier aléatoirement les enregistrements en sachant que T.Id est unique :</p>
<div class="codecolorer-container sql blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">SELECT</span> &nbsp;<span style="color: #66cc66;">*</span><br />
<span style="color: #993333; font-weight: bold;">FROM</span> &nbsp; &nbsp;tTop <span style="color: #993333; font-weight: bold;">AS</span> T1<br />
<span style="color: #993333; font-weight: bold;">WHERE</span> &nbsp; T1<span style="color: #66cc66;">.</span>Id <span style="color: #993333; font-weight: bold;">IN</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> TOP <span style="color: #cc66cc;">3</span> Id<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">FROM</span> &nbsp; tTop T<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">WHERE</span> &nbsp;T<span style="color: #66cc66;">.</span>Nom <span style="color: #66cc66;">=</span> T1<span style="color: #66cc66;">.</span>Nom<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">ORDER</span> <span style="color: #993333; font-weight: bold;">BY</span> Rnd<span style="color: #66cc66;">&#40;</span>T<span style="color: #66cc66;">.</span>Id<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;t<span style="color: #66cc66;">.</span>Id<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#41;</span><br />
<span style="color: #993333; font-weight: bold;">ORDER</span> <span style="color: #993333; font-weight: bold;">BY</span> T1<span style="color: #66cc66;">.</span>Nom<span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;T1<span style="color: #66cc66;">.</span>Id;</div></div>
<p>Comme vous pouvez le constater, on perd la notion de Top 3 par Nom car pour chaque T1.Id, la sous-requête recalcule une liste d&rsquo;Id différente&#8230;</p>
<p><strong>La requête SQL finale</strong></p>
<div class="codecolorer-container sql blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">SELECT</span> &nbsp;<span style="color: #66cc66;">*</span><br />
<span style="color: #993333; font-weight: bold;">FROM</span> &nbsp; &nbsp;tTop <span style="color: #993333; font-weight: bold;">AS</span> T1<br />
<span style="color: #993333; font-weight: bold;">WHERE</span> &nbsp; T1<span style="color: #66cc66;">.</span>Id <span style="color: #993333; font-weight: bold;">IN</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> TOP <span style="color: #cc66cc;">3</span> Id<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">FROM</span> &nbsp; tTop T<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">WHERE</span> &nbsp;T<span style="color: #66cc66;">.</span>Nom <span style="color: #66cc66;">=</span> T1<span style="color: #66cc66;">.</span>Nom<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">ORDER</span> <span style="color: #993333; font-weight: bold;">BY</span> Rnd<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">-</span><span style="color: #66cc66;">&#40;</span> T<span style="color: #66cc66;">.</span>Id <span style="color: #66cc66;">+</span> Timer<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;t<span style="color: #66cc66;">.</span>Id<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#41;</span><br />
<span style="color: #993333; font-weight: bold;">ORDER</span> <span style="color: #993333; font-weight: bold;">BY</span> T1<span style="color: #66cc66;">.</span>Nom<span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;T1<span style="color: #66cc66;">.</span>Id;</div></div>
<p><strong>Explications</strong><br />
On s&rsquo;appuie sur deux particularités d&rsquo;Access :</p>
<p>La <strong>première</strong> est que si l&rsquo;on passe un nombre négatif en argument à la fonction Rnd(), elle retourne toujours le même nombre aléatoire. Ceci permet d&rsquo;avoir une liste constante d&rsquo;Id pour chaque Nom.</p>
<p>La <strong>deuxième</strong> va nous permettre d&rsquo;obtenir une liste différente d&rsquo;Id entre chaque appel de la requête principale. Pour ajouter un zeste d&rsquo;aléatoire on utilise la fonction Timer() en argument de la fonction Rnd(). Heureusement, Access ne met pas à jour le timer() pendant tout le temps d&rsquo;exécution de la requête. La valeur du timer au démarrage de la requête est conservé jusqu&rsquo;à la fin de son exécution ou de sa prochaine actualisation (dans un formulaire prendre un recordset avec <strong>snapshot</strong> pour éviter une mise à jour via modification du jeu d&rsquo;enregistrements sous-jacent).</p>
<p><strong>Remarques</strong><br />
L&rsquo;ajout d&rsquo;une deuxième colonne de tri (T.Id) dans la sous-requête permet de s&rsquo;assurer que le top 3 retournera toujours que 3 lignes au maximum même si des ex-aequo subsistent après ORDER BY RND(-(T.Id+Timer())).</p>
<p>La présence de la sous-requête entraîne un temps d&rsquo;exécution long de la requête qui sera donc réservée pour des tables ayant peu de lignes (~1000).<br />
@+</p>
<p>Philippe</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
