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