|
Requêtes: Simplifier les requêtes d'action, dans le code |
Author(s)
|
|
---Soumis par Dev Ashish---
Simplifier les requêtes d'action, dans le code.
Avez-vous déjà implémenté uin processus en mode batch
d'importation, de mise à jour suivi d'exportation sous Access, utilisant
Execute ou RunSQL? Si oui, vous savez probablement la difficulté associé à la
maintenance de ces codes SQL. Pour être honnête, je me suis tiré les cheveux
à maintes occasions avec ce problème.
C'est-à-dire jusqu'à ce que je réalise que je peux
utiliser une table Access et un logique toute simple qui non seulement réduit
le nombre de lignes de code SQL inclus dans le code VBA, mais, de plus, rend les
requêtes auto documentées. On peut continuer à définir les requêtes avec
Access QBE et ne pas à avoir à inclure tout ces énoncés SQL dans le code.
Je me défini une table, tblSQL, comme
Field Name |
Data Type |
Description |
SQLID |
Autonumber |
Clé primaire pour la table. |
SQLSequence |
Long Integer |
Détermine la séquence d'exécution des énoncés SQL. |
CalledFromProc |
Text |
Nom de la procédure utilisant cette requête. |
SQLString |
Memo |
Énoncé SQL à utiliser. |
SQLDescription |
Memo |
Description de ce que fait cet énoncé SQL. |
Le champ de description représente le contenu actuel de chaque champ.
L'idée derrière le processus est de sauvegarder les énoncés SQL en
séquence, de par le numéro de séquence SQLSequence à
l'intérieur de chaque processus CalledFromProc
(réutilisable, si requis, à divers points de votre programme). Un exemple de
valeurs dans cette table peut être comme suit:
SQL ID |
SQL
Seq-
uence |
Called
From
Proc |
SQL
String |
SQL
Description |
3 |
1 |
Batch
Process1 |
UPDATE DISTINCTROW Table1 INNER JOIN Table2 ON Table1.SomeID =
Table2.SomeID SET Table2.SomeField = [Table1].[AnotherField]
WHERE (((Table2.ThirdField)="Microsoft Access")); |
Gets the value for SomeID from Table2 for ThirdField="Microsoft
Access" |
4 |
2 |
Batch
Process1 |
UPDATE DISTINCTROW Table2 SET Table2.LastName =
fRemoveChar([LastName],"_"), Table2.FirstName =
fRemoveChar([FirstName],"_"); |
Removes Underscores from First and Last names for all records and replaces
it with an underscore. |
5 |
3 |
Batch
Process1 |
UPDATE DISTINCTROW Table2 INNER JOIN MasterTable ON Table2.SomeID =
MasterTable.ThisID SET Table2.ThisID = MasterTable.TheID WHERE (((Table2.SomeID) Is
Null)); |
Get the ThisID for everybody from MasterTable table |
Créer un formulaire lié à cette table et en y contenant tous les champs.
Vous pouvez ne pas inclure SQLID si vous le désirez. Le formulaire vous
permet de sauvegarder, modifier ou de voir les énoncés SQL.
Les étapes requises pour exécuter ces requêtes en séquence, les unes après
les autres, sont toutes simples.
En principe, vous devez:
- Identifier les énoncés SQL requis pour exécuter la procédure
"batch" requise.
- Ordonner les énoncé SQL selon leur séquence, pour la procédure
identifiée.
- Remplacer tous les guillemets par Chr(34) dans l'énoncé SQL.
- Exécuter la requête d'action.
Avec le traitement d'erreur, et une fonction pour remplacer les guillemets,
nous avons tout ce qu'il nous faut pour procéder. Un exemple simple
d'utilisation suit:
Sub sSomeSubRoutine()
Dim lodb As Database, strSQL As String
Dim loSQLRS As Recordset, lngCurrent As Long
Dim varTmp As Variant
Const cERR_GRACEFUL_EXIT = vbObjectError + 20
On Local Error GoTo Err_handler
varTmp = SysCmd(acSysCmdSetStatus, "Starting Batch process...")
Set lodb = CurrentDb
Set loSQLRS = lodb.OpenRecordset("Select * from tblSQL where" _
& " CalledFromProc='sStartOutSiderProcess'", dbOpenSnapshot)
lngCurrent = 1
With loSQLRS
.FindFirst "SQLSequence=" & lngCurrent
If .NoMatch Then Err.Raise cERR_GRACEFUL_EXIT
Do While Not .NoMatch
strSQL = adhHandleQuotes(!SQLString)
lodb.Execute strSQL, dbFailOnError
lngCurrent = lngCurrent + 1
.FindFirst "SQLSequence=" & lngCurrent
Loop
End With
Exit_Here:
varTmp = SysCmd(acSysCmdClearStatus)
Set loSQLRS = Nothing
Set lodb = Nothing
Exit Sub
Err_handler:
Dim strXX As String
Select Case Err.Number
Case 3065:
strXX = "You can only run Action queries by the Execute method."
strXX = strXX & vbCrLf & "Please change the SQL to an action statement."
strXX = strXX & vbCrLf & vbCrLf & loSQLRS!SQLString
MsgBox strXX, vbCritical + vbOKOnly, "Error in SQL Statement"
Case 3075:
strXX = "The following SQL statement has syntax error."
strXX = strXX & vbCrLf & "Please verify the SQL string and try again."
strXX = strXX & vbCrLf & vbCrLf & loSQLRS!SQLString
MsgBox strXX, vbCritical + vbOKOnly, "Error in SQL Statement"
Case cERR_GRACEFUL_EXIT:
Case Else:
strXX = "Proc: sSomeSubRoutine"
strXX = strXX & vbCrLf & "Error #: " & Err.Number
strXX = strXX & vbCrLf & "Description: " & Err.Description
If Not (loSQLRS Is Nothing) And Not (lodb Is Nothing) Then
strXX = strXX & vbCrLf & "The last action query " & vbCrLf & vbCrLf & _
loSQLRS!SQLString & vbCrLf & vbCrLf & "affected " & _
lodb.RecordsAffected & " records"
End If
MsgBox strXX, vbExclamation + vbOKOnly, "Runtime Error"
End Select
Resume Exit_Here
End Sub
Public Function adhHandleQuotes(strValue As String) As String
Const QUOTE As String = """"
adhHandleQuotes = QUOTE & adhReplace(strValue, QUOTE, _
QUOTE & " & Chr$(34) & " & QUOTE) & QUOTE
End Function
Function adhReplace(ByVal varValue As Variant, _
ByVal strFind As String, ByVal strReplace As String) As Variant
Dim intLenFind As Integer
Dim intLenReplace As Integer
Dim intPos As Integer
If IsNull(varValue) Then
adhReplace = Null
Else
intLenFind = Len(strFind)
intLenReplace = Len(strReplace)
intPos = 1
Do
intPos = InStr(intPos, varValue, strFind)
If intPos > 0 Then
varValue = Left(varValue, intPos - 1) & _
strReplace & Mid(varValue, intPos + intLenFind)
intPos = intPos + intLenReplace
End If
Loop Until intPos = 0
End If
adhReplace = varValue
End Function
Les avantages de cette approche:
- L'énoncé SQL est fin prêt à être copié, sans avoir à ajouter ou à
enlever des caractères de continuation.
- Pour changer l'ordre d'exécution? Tout simple, seulement à changer SQLSequence,
évitant de couper-coller!
- Le champ SQLDescription rend votre code plus aisé à comprendre.
Vous pouvez même définir un état, avec les champs selon l'ordre des
séquence, et qui voilà tout simplement la documentation appropriée !
- Est-il besoin de mentionner le nombre de lignes de code que vous venez
d'éliminer,. remplacé par un appel à une simple procédure?
- Vous désirez tester un différent ordonnancement des énoncés?
Simplement renuméroter les séquences. Ainsi, pour "tester" ce
qui se passe si 11 et 12 ne sont pas exécutés, temporairement les
renuméroter, comme 20 et 21, puis arrêter l'exécution après 19, par
exemple.
|