La idea de esta entrada es demostrar que podemos crear agentes programados que conectan con una base de datos de cualquier ERP para generar ficheros alternativos que nos puedan servir para cualquier finalidad.
Por ejemplo podríamos crear desde Visual Studio un agente que se ejecute en modo systray (VxD) y que cada cierto tiempo conecte con una base de datos del ERP que empleemos en la empresa, en concreto extraer cierta información de la base Oracle instalada en la Intranet (modo protegido del exterior) y subir un fichero Microsoft Access generado (mdb), y una serie de imágenes a Internet.
El proyecto lo realice hace tiempo de forma remota mediante conexión VNC. La conexión se puede efectuar mediante VNC personal (requiere licencia). Es necesario configurar el router y activar el puerto 5900, y el NAT para redirigir las peticiones al ordenador desde el que deseamos conectar (cada router se realiza de una forma en concreto, el modelo que trabaje fue el 3COM).
Muy importante. Para conectar desde Visual Basic con Oracle, es necesario instalar el complemento OO40, el Oracle Objects For OLE.
El servidor con que que desplegué el proyecto es un Oracle 10g, mediante una ip local 192.168.1.101 y al puerto TCP 1521.
Se programa mediante el objeto de oracle 0040(ver documento desarrollador), para ello es necesario instalar el cliente de Oracle (oracle client) en la máquina donde se encuentra la pasarela o aplicación que deseemos desarrollar. Esto instalará un cliente ODBC especifico para Oracle (instantclient-odbc-win32-10.1.0.5-20060419)
Una vez estudiado los ficheros conectaremos con el tnsnames.ora. En concreto, he conectado con el ERP de AS Fas-5, pero podría ser otro. Para ello es necesario disponer de una idea del modelo de tablas que componen el ERP con que que se va a trabajar.
Para conectar desde visual podemos instalar el developer tools.
El código de para conectar es sencillo:
Set OraSession = CreateObject(“OracleInProcServer.XOraSession”)
Set OraDatabase = OraSession.OpenDatabase(‘NOMBRE_SERVIDOR’, ‘USER/PASS’, 0&)
Luego para trabajar con la conexión se referencia mediante OraDatabase.xxxxxxxxxxxxx, donde las x corresponden a las tablas.
Una aplicación que nos permitirá a priori ver registros y trabajar con Oracle desde una estación remota o de desarrollo puede ser por ejemplo, Oracle Maestro.
https://www.sqlmaestro.com/products/oracle/maestro/
Ejemplo de código:
Dim fotos As String
Dim ftp As New ChilkatFTP
Dim success As Integer
Dim fs
Notify.dwInfoFlags = &H1
'Ponemos el archivo a cero
Set fs = CreateObject("Scripting.FileSystemObject")
fs.CopyFile App.Path & "\Mibase-access.mdb", rutadedatosg & "\"
Set fs = Nothing
'Comencemos el proceso de conversión de formato DBF a MDB
'Abrimos la base de datos
estado.Caption = "Comenzando la conversión de datos antes del envio..."
Notify.szInfoTitle = "PASARELA Mibase-access"
Notify.szInfo = "Comenzando la conversión de datos Oracle del catálogo..."
Shell_NotifyIcon NIM_MODIFY, Notify
Dim oConn, oConn2, Caccess As ADODB.Connection
Dim oRs, rarticulos, rfamilia, rsubfamilia, ratributos, rtarifas As ADODB.Recordset
Dim Rproductos As ADODB.Recordset
'Contadores generales.
Dim clineas, Cfamilias, csubfamilias, cproductos, catributos, ctarifas, cimagenes As Long
Dim CadenaAccess
Dim sql, contadordbf
CadenaAccess = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & rutadedatosg & "\" & "Mibase-access.mdb;"
'Procedimiento de importación de Artículos
'Preparamos el conector Access
' abir la conexión.
Set Caccess = New ADODB.Connection
Caccess.Open CadenaAccess
' Open recordset with data from Employee table.
Set rarticulos = New ADODB.Recordset
rarticulos.CursorType = adOpenKeyset
rarticulos.LockType = adLockOptimistic
rarticulos.Open "linea", Caccess, , , adCmdTable
estado.Caption = "Abriendo fichero mdb temporal..."
Notify.szInfoTitle = "PASARELA Mibase-access"
Notify.szInfo = "El fichero temporal Mibase-access.mdb abierto correctamente ..."
Shell_NotifyIcon NIM_MODIFY, Notify
Dim OraSession As Object 'Declaracion de variables as OLE Objects
Dim OraDatabase As Object
Dim OraDynaset As Object
Dim IDG, DESCG, DESCAB As Variant
Dim contadorLineas As Long
Set OraSession = CreateObject("OracleInProcServer.XOraSession")
Set OraDatabase = OraSession.DbOpenDatabase("FAS5_Mibase-access", "DWH/Mibase-accessDWH", 0&)
Set OraDynaset = OraDatabase.DbCreateDynaset("Select * from Base-Oracle.ASMATA19 ORDER BY VALCOD", 0&)
contadorLineas = 0
Do While Not OraDynaset.EOF
rarticulos.AddNew
rarticulos("ID") = OraDynaset.Fields("VALCOD").Value
rarticulos("descripcion") = OraDynaset.Fields("VALDES").Value
rarticulos("descabreb") = OraDynaset.Fields("VALDEA").Value
OraDynaset.MoveNext
contadorLineas = contadorLineas + 1
rarticulos.Update
Loop
Set OraDynaset = Nothing
'Comenzamos con el movimiento de registros de ORACLE
estado.Caption = "Líneas de productos procesadas de ASMATA19..."
Notify.dwInfoFlags = &H1
Notify.szInfoTitle = "PASARELA Mibase-access, Fase 1"
Notify.szInfo = "Nº de líneas procesadas : " & CStr(contadorLineas)
clineas = contadorLineas
Shell_NotifyIcon NIM_MODIFY, Notify
rarticulos.Close
'Procedemos a volcar las familias al motor jet access
Set rfamilia = New ADODB.Recordset
rfamilia.CursorType = adOpenKeyset
rfamilia.LockType = adLockOptimistic
rfamilia.Open "familia", Caccess, , , adCmdTable
Set OraDynaset = OraDatabase.DbCreateDynaset("Select vagcod,vagdes,vagdea,valcod from Base-Oracle.ASMATA13 ORDER BY VAGCOD", 0&)
contadorLineas = 0
Do While Not OraDynaset.EOF
If OraDynaset.Fields("VAGCOD").Value <> "" Then
rfamilia.AddNew
rfamilia("ID") = OraDynaset.Fields("VAGCOD").Value
rfamilia("descripcion") = OraDynaset.Fields("VAGDES").Value
rfamilia("Descabre") = OraDynaset.Fields("VAGDEA").Value
'Id de relacion
rfamilia("IDLinea") = OraDynaset.Fields("VALCOD").Value
contadorLineas = contadorLineas + 1
rfamilia.Update
End If
OraDynaset.MoveNext
Loop
rfamilia.Close
estado.Caption = "Familias de productos procesadas sin agrupar de ASMATA13..."
Notify.szInfoTitle = "PASARELA Mibase-access, Fase 2"
Notify.szInfo = "Nº de familias no agrupadas procesadas : " & CStr(contadorLineas)
Cfamilias = contadorLineas
Shell_NotifyIcon NIM_MODIFY, Notify
'Procedemos a volcar las SUBFAMILIAS al motor jet de access
Set rsubfamilia = New ADODB.Recordset
rsubfamilia.CursorType = adOpenKeyset
rsubfamilia.LockType = adLockOptimistic
rsubfamilia.Open "subfamilia", Caccess, , , adCmdTable
Set OraDynaset = OraDatabase.DbCreateDynaset("Select vfacod,vfades,vfadea,vagcod from Base-Oracle.ASMATA12 ORDER BY VFACOD", 0&)
contadorLineas = 0
Do While Not OraDynaset.EOF
If OraDynaset.Fields("VFACOD").Value <> "" Then
rsubfamilia.AddNew
rsubfamilia("ID") = OraDynaset.Fields("VFACOD").Value
rsubfamilia("descripcion") = OraDynaset.Fields("VFADES").Value
rsubfamilia("Descabre") = OraDynaset.Fields("VFADEA").Value
'Id de relacion
rsubfamilia("IDFAMILIA") = OraDynaset.Fields("VAGCOD").Value
contadorLineas = contadorLineas + 1
rsubfamilia.Update
End If
OraDynaset.MoveNext
Loop
rsubfamilia.Close
estado.Caption = "Subfamilia de productos procesadas sin agrupar de ASMATA12..."
Notify.szInfoTitle = "PASARELA Mibase-access, Fase 3"
Notify.szInfo = "Nº de subfamilias procesadas no agrupadas : " & CStr(contadorLineas)
csubfamilias = contadorLineas
Notify.dwInfoFlags = &H1
Shell_NotifyIcon NIM_MODIFY, Notify
Sleep 3000
'Comenzamos con el movimiento ficha general. ASMAAR01
'Campos
Set Rproductos = New ADODB.Recordset
Rproductos.CursorType = adOpenKeyset
Rproductos.LockType = adLockOptimistic
Rproductos.Open "Productos", Caccess, , , adCmdTable
Set OraDynaset = OraDatabase.DbCreateDynaset("Select ARCARF,ARCARC,VALCOD,VAGCOD,VFACOD,ULTMOD,ARDES1,ARDES2,ARDEAB from Base-Oracle.ASMAAR01", 0&)
contadorLineas = 0
Do While Not OraDynaset.EOF
If OraDynaset.Fields("ARCARF").Value <> "" Then
'prueba = OraDynaset.Fields("ARCARF").Value
Rproductos.AddNew
Rproductos("ID") = OraDynaset.Fields("ARCARF").Value
Rproductos("ID2") = OraDynaset.Fields("ARCARC").Value
Rproductos("IDLINEA") = OraDynaset.Fields("VALCOD").Value
Rproductos("IDFAMILIA") = OraDynaset.Fields("VAGCOD").Value
Rproductos("IDSUBFAMILIA") = OraDynaset.Fields("VFACOD").Value
Rproductos("FECHAMOD") = OraDynaset.Fields("ULTMOD").Value
Rproductos("DESCRIPCION") = OraDynaset.Fields("ARDES1").Value
Rproductos("DESCRIPCION2") = OraDynaset.Fields("ARDES2").Value
Rproductos("DESC3") = OraDynaset.Fields("ARDEAB").Value
contadorLineas = contadorLineas + 1
Rproductos.Update
End If
OraDynaset.MoveNext
Loop
Rproductos.Close
estado.Caption = "Productos de la pestaña general de ASMAAR01..."
Notify.szInfoTitle = "PASARELA Mibase-access, Fase 4 (productos)"
Notify.szInfo = "Nº de productos procesados no agrupados : " & CStr(contadorLineas)
cproductos = contadorLineas
Notify.dwInfoFlags = &H1
Shell_NotifyIcon NIM_MODIFY, Notify
Sleep 3000
'Comenzamos con el movimiento ficha atributos. ASMAAR20
'Campos y tipos.
'EMCOD varchar2
'VATCOD varchar1
'ARCARF varchar 15 Relación con la tabla tarifas, puede ser el id
'ARTLIN no nulo y numero
'ATRTEX varchar de 60 caracteres, es la descripción
'MARCAC varchar de 1
'POPERA carchar 10
'ULTMOD tipo fecha , útima modificacion
'HORMOD tipo fecha
'IDIOMA varchar 2
Set ratributos = New ADODB.Recordset
ratributos.CursorType = adOpenKeyset
ratributos.LockType = adLockOptimistic
ratributos.Open "Atributos", Caccess, , , adCmdTable
Set OraDynaset = OraDatabase.DbCreateDynaset("Select * from Base-Oracle.ASMAAR20", 0&)
contadorLineas = 0
Do While Not OraDynaset.EOF
ratributos.AddNew
ratributos("EMCODI") = OraDynaset.Fields("EMCODI").Value
ratributos("VATCOD") = OraDynaset.Fields("VATCOD").Value
ratributos("ARCARF") = OraDynaset.Fields("ARCARF").Value
ratributos("ATRLIN") = OraDynaset.Fields("ARTLIN").Value
ratributos("ARTTEX") = OraDynaset.Fields("ARTTEX").Value
ratributos("MARCAC") = OraDynaset.Fields("MARCAC").Value
ratributos("POPERA") = OraDynaset.Fields("POPERA").Value
ratributos("ULTMOD") = OraDynaset.Fields("ULTMOD").Value
ratributos("IDIOMA") = OraDynaset.Fields("IDIOMA").Value
contadorLineas = contadorLineas + 1
ratributos.Update
OraDynaset.MoveNext
Loop
ratributos.Close
estado.Caption = "Atributos de los productos ASMAAR20 ..."
Notify.szInfoTitle = "PASARELA Mibase-access, Fase 5 (atributos asociados)"
Notify.szInfo = "Nº de atributos procesados: " & CStr(contadorLineas)
catributos = contadorLineas
Notify.dwInfoFlags = &H1
Shell_NotifyIcon NIM_MODIFY, Notify
' Comenzamos con las tarifas fase 6
Set rtarifas = New ADODB.Recordset
rtarifas.CursorType = adOpenKeyset
rtarifas.LockType = adLockOptimistic
rtarifas.Open "tarifas", Caccess, , , adCmdTable
Set OraDynaset = OraDatabase.DbCreateDynaset("Select * from Base-Oracle.ASMAAR20", 0&)
contadorLineas = 0
Do While Not OraDynaset.EOF
rtarifas.AddNew
rtarifas("TRCODI") = OraDynaset.Fields("TRCODI").Value
rtarifas("VATCOD") = OraDynaset.Fields("VATCOD").Value
rtarifas("ARCARF") = OraDynaset.Fields("ARCARF").Value
rtarifas("TRFINI") = OraDynaset.Fields("TRFINI").Value
rtarifas("TRFFIN") = OraDynaset.Fields("TRFFIN").Value
rtarifas("TRPRVE") = OraDynaset.Fields("TRPRVE").Value
rtarifas("POPERA") = OraDynaset.Fields("POPERA").Value
rtarifas("ULTMOD") = OraDynaset.Fields("ULTMOD").Value
rtarifas("MARCAC") = OraDynaset.Fields("MARCAC").Value
rtarifas("EMCODI") = OraDynaset.Fields("EMCODI").Value
rtarifas("HORMOD") = OraDynaset.Fields("HORMOD").Value
rtarifas("TRIMP1") = OraDynaset.Fields("TRIMP1").Value
rtarifas("TRIMP2") = OraDynaset.Fields("TRIMP2").Value
rtarifas("TRIMP3") = OraDynaset.Fields("TRIMP3").Value
rtarifas("TRIMP4") = OraDynaset.Fields("TRIMP4").Value
rtarifas("UNIPRE") = OraDynaset.Fields("UNIPRE").Value
contadorLineas = contadorLineas + 1
rtarifas.Update
OraDynaset.MoveNext
Loop
rtarifas.Close
estado.Caption = "Tarifas de los productos ASMATR01 ..."
Notify.szInfoTitle = "PASARELA Mibase-access, Fase 6 (tarifas asociadas)"
Notify.szInfo = "Nº de tarifas procesados: " & CStr(contadorLineas)
ctarifas = contadorLineas
Notify.dwInfoFlags = &H1
Shell_NotifyIcon NIM_MODIFY, Notify
estado.Caption = "Final de movimientos de registros de la base ..."
Notify.szInfoTitle = "Preparándose log y otras tareas de mantenimiento ..."
Notify.szInfo = "Actualizado el Log y otras tareas de mantenimiento ..."
Shell_NotifyIcon NIM_MODIFY, Notify
'FIN DE MOVIMIENTOS DE LA BASE
Caccess.Close
Set ratributos = Nothing
Set rtarifas = Nothing
Set rfamilia = Nothing
Set rsubfamilia = Nothing
Set Rproductos = Nothing
Set rarticulos = Nothing
Set Caccess = Nothing
Set OraDatabase = Nothing
'Fin de movimientos
estado.Caption = "El proceso de conversión finalizado correctamente..."
Notify.szInfoTitle = "PASARELA Mibase-access"
Notify.szInfo = "El proceso de conversión ha finalizado correctamente..."
Shell_NotifyIcon NIM_MODIFY, Notify
Resumen de cómo conectar:
Dim Base As Object
Dim Reg as Object
Set Base = OraSession.DbOpenDatabase(“SERVIDORORACLE”, “USUARIO/USR”, 0&)
Set Reg = Base.DbCreateDynaset(“Select * from PATENTE”, 0&)
‘ Aqui ya tenemos el recordset
‘ Puedo realizar cualquier operación si problemas
Set Reg = nothing
Set Base = nothing
Forma 2.- (ADO)
– Crear un Form
– Clic en Proyecto, y Componente
– Activar la Casilla Microsoft ADO data control 6.0 y Aceptar
– Clic en Ver, y Cuadro de Herramienta.
– Doble clic en el Control Adodc (se creo el control adodc1)
– Click con el Botón derecho y clic en propiedades.
– Clic en Generar,clic en Microsoft OLE DB Provider for Oracle y Clic en Siguiente
– Escribir en Nombre de Servidor SERVIDORORACLE, USUARIO y USR en donde corresponde a Usuario y password respectivamente.
– Haz Clic en Probar conexión para asegurarte de que este bien hecho.
– Clic en Aceptar.
– Clic en Autentificacion y luego escribir USUARIO y USR nuevamente donde corresponde a
Usuario y password respectivamente.
– Clic en Origen de Registros y luego seleccionar en tipo de comando (2 – adCmdTable)
– Luego selecciona en tabla, la tabla PATENTE y luego aceptar
Con esto estas conectado y ademas tienes el recordset con el control ADOdc1
Recuerda para finalizar, que es aconsejable crear un instalador con todos los complementos y archivos necesarios para distribuir el proyecto, recomiendo Inno Setup.
Recomiendo lectura libro: Oracle Programing with Visual Basic de Nick Snowdon








