|
||||||||||||||||||||||||||||||||||||||
Simplificar Consultas Ação por código |
||||||||||||||||||||||||||||||||||||||
Já teve que criar um processo de importação/atualização/exportação usando os métodos Execute ou RunSQL em lote?Autor: Dev Hashish |
||||||||||||||||||||||||||||||||||||||
|
Se já, então conhece as dores de ter que voltar ao seu código SQL para atualizá-lo. Sendo bem honesto, já cheguei bem próximo de arrancar os cabelos em diversas ocasiões. Até que um dia me toquei que podia usar uma tabela Access e um pouco de lógica não apenas para "aparar" possíveis centenas de linhas de código SQL e VBA, além de fazer com que as próprias consultas sejam autoducumentadas. Podemos continuar a alterar as consultas criadas com o assistente e a grade sem ter que ficar se preocupando com a concatenação de todo o SQL em código. Defini uma tabela assim:
O campo DescricaoSQL representa o conteúdo real de cada campo. A idéia por trás desse processo é salvar os comandos SQL na ordem em que devem ser executados, assegurando sua identidade por mei do número em SequenciaSQL. Se tivermos diversas funções que usam as consultas ação, elas ainda podem ser salvas na mesma tabela desde que seja usado o campo ChamadoDaProc para categorizar os comandos SQL. Anguma entradas típicas na tabela seriam mais ou menos assim:
Criamos um formulário simples, vinculado a esta tabela, contendo todos os campos. SQLID pode ficar de fora. Este formulário vai fornecer os meio para salvar, alterar e ver os comandos SQL salvos na tabela. Os passos requeridos para executar estas consultas em seqüência como o seriam se as consultas estivessem ordenadas no código é, na verdade, bastante simples. Precisamos, basicamente, dos seguintes passos:
Com uma rotina de erro para tratar os probleminhas de sintaxe e uma função para substituir as aspas, temos tudo para continuar. Uma amostra simples da utilização deste conceito é o código a seguir:
'*************** Code Start ***************
' Este código foi escrito originalmente por Dev Ashish.
' Ele não deve ser alterado ou distribuíso,
' exceto como parte de um aplicativo.
' Use-o livremente em seus aplicativos,
' desde que esta nota de copyright permaneça inalterada.
'
' Código cortesia de
' Dev Ashish
'
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, "Iniciando o processo em lote...")
Set lodb = CurrentDb
Set loSQLRS = lodb.OpenRecordset("Select * from tblSQL where" _
& " ChamadoDaProc='sIniciaProcessoExterno'", dbOpenSnapshot)
lngCurrent = 1
With loSQLRS
.FindFirst "SequenciaSQL=" & lngCurrent
If .NoMatch Then Err.Raise cERR_GRACEFUL_EXIT
Do While Not .NoMatch
strSQL = adhHandleQuotes(!SQLString)
lodb.Execute strSQL, dbFailOnError
lngCurrent = lngCurrent + 1
.FindFirst "SequenciaSQL=" & 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: 'SQL é um comando SELECT
strXX = "Apenas consultas ação podem ser executadas pelo método Execute."
strXX = strXX & vbCrLf & "Altere o comando SQL para um comando ação."
strXX = strXX & vbCrLf & vbCrLf & loSQLRS!SQLString
MsgBox strXX, vbCritical + vbOKOnly, "Erro em comando SQL"
Case 3075: 'Erro de sintaxe no comando SQL
strXX = "O comando SQL a seguir tem um erro de sintaxe."
strXX = strXX & vbCrLf & "Verifique a string SQL e tente novamente."
strXX = strXX & vbCrLf & vbCrLf & loSQLRS!SQLString
MsgBox strXX, vbCritical + vbOKOnly, "Erro em comando SQL"
Case cERR_GRACEFUL_EXIT:
Case Else:
strXX = "Proc: sSomeSubRoutine"
strXX = strXX & vbCrLf & "Erro Nº: " & Err.Number
strXX = strXX & vbCrLf & "Descrição: " & Err.Description
If Not (loSQLRS Is Nothing) And Not (lodb Is Nothing) Then
strXX = strXX & vbCrLf & "A última consulta ação " & vbCrLf & vbCrLf & _
loSQLRS!SQLString & vbCrLf & vbCrLf & "afetou " & _
lodb.RecordsAffected & " registros"
End If
MsgBox strXX, vbExclamation + vbOKOnly, "Erro de execução"
End Select
Resume Exit_Here
End Sub
Public Function adhHandleQuotes(strValue As String) As String
' Corrige todas as ocorrências de aspa em uma string
' dividindo-a e inserindo Chr$(34) sempre que
' encontrar aspas dentro da string. Desta forma o Jet pode
' tratar as strings nas consultas.
'
' Encontrado em Access 97 Developer's Handbook
' por Litwin, Getz, and Gilbert (Sybex)
' Copyright 1997. Todos os direitos reservados.
'
' Solução sugerida por Jurgen Welz, um leitor diligente.
' Entrada:
' strValue: Valor a ser corrigido.
' Saida:
' Return value: O texto com as aspas corrigidas.
' Exige:
' adhReplace (ou alguma outra função que substitua
' uma string por outra)
'
' Exemplo:
' adhHandleQuotes("John "Big-Boy" O'Neil") returns
' "John " & Chr$(34) & "Big-Boy" & Chr$(34) & " O'Neil"
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
' Substitui todas as instâncias de strFind por strReplace em varValue.
' Encontrado em Access 97 Developer's Handbook
' por Litwin, Getz, and Gilbert (Sybex)
' Copyright 1997. Todos os direitos reservados.
' Entrada:
' varValue: Valor a ser modificado
' strFind: String a localizar
' strReplace: String para substituir strFind '
' Saida:
' Return value: varValue, com todas as ocorrências de strFind
' substituídas por strReplace.
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
'****************** Final do Código *****************
Os benefícios deste trabalho:
|
||||||||||||||||||||||||||||||||||||||