Reinstalando todo...
Cita de: Búho
Primer ejemplo:Abro simplemente el Recordset del fichero de texto.
Option Explicit
Function TestSchema()
Dim db As DATABASE, rs As Recordset
Set db = OpenDatabase("c:\my documents", False, _
False,"TEXT;Database=c:\my documents;table=contacts.txt")
Set rs = db.OpenRecordset("contacts.txt")
rs.MoveLast
Debug.Print "Record count= " & rs.RecordCount
rs.Close
End Function
'========================================
Ejemplo 2
Se crea una tabla linkada al fichero de texto:
Option Explicit
Function LinkSchema()
Dim db As DATABASE, tbl As TableDef
Set db = CurrentDb()
Set tbl = db.CreateTableDef("Linked Text")
tbl.Connect = "Text;DATABASE=c:\Mis Documentos;TABLE=contacts.txt"
tbl.SourceTableName = "contacts.txt"
db.TableDefs.Append tbl
db.TableDefs.Refresh
End Function
Cita de: quien
Cuando ejecuto mi MDB en mi ordenador, todo funciona bien. Sin embargo si la traslado a otro PC, el usuario me indica que se producen errores, pues faltan Referencias a DLL u OCX dentro del proyecto. ¿Como puedo controlar este tema desde código?
'Francisco J. García Aguado (Bhuo)
'Agosto de 2002
Function MiraReferenciasVBA()
Dim Ref As Reference
'Sacado de la ayuda de Access para ver si se ha
'roto alguna referencia del proyecto de VBA.
'Bhúo, Agosto de 2002
'Puede servir para cuando distribuyamos una aplicación
'con referencias externas a funciones inmersas en: OCX,DLL, MDE, MDB...)
'que nosotros en el proyecto hemos referenciado desde una determinada ubicación
'local de nuestro PC y a la hora de ejecutar el programa el usuario, pueda dar errores
'por no tener dichas referencias o tenerlas en otra ubicación distinta
'y de esta forma el usuario nos pueda avisar de esta contingencia.
'Esta función se puede poner en el formulario de inicio de la aplicación
'para avisar al usuario de este tema.
For Each Ref In References
If Ref.IsBroken = False Then
' este msgbox es puramente informativo de las referencias que están OK
' y es para probar este código.
MsgBox "Nombre de la Referencia: " & Ref.Name & vbCrLf _
& "En la ruta: " & Ref.FullPath & vbCrLf _
& "Versión de la Referencia: " & Ref.Major & "." & Ref.Minor, vbInformation + vbOKOnly, "Referencias en VBA"
Else
' referencia rota
MsgBox "Nombre de la Referencia rota:" & Ref.Name & vbCrLf _
& "Ruta Origina: " & Ref.FullPath & vbCrLf _
& "GUID completo de la Referencia: " & Ref.Guid, vbCritical + vbOKOnly, "AVISO: Servicio de mantenimiento del programa 95-22222222."
'aquí la acción a seguir...
'Sacado también de la ayuda de Access.
'En este ejemplo, se podría poner ruta completa, mediante
'un dialogo de Windows e intentar referenciar de nuevo
'la referencia rota o bien abandonar la aplicación.
'En este caso ponemos una ruta fija que sirva de ejemplo:
'C:\Windows\System\Mscal.ocx
'Recordar que el nombre y Path original de la referencia
'sería ref.FullPath
If CrearNuevaReferencia("C:\Windows\System\Mscal.ocx") = False Then
MsgBox "No se ha podido regenerar la referencia.", vbCritical + vbOKOnly, "Aviso"
Else
MsgBox "La Referencia, " & Ref.FullPath & " se ha establecido correctamente.", vbExclamation + vbOKOnly, "Correcto"
End If
End If
Next Ref
End Function
'***************************************
Function CrearNuevaReferencia(PathCompletoFichero As String) As Boolean
Dim Ref As Reference
On Error GoTo Error_CrearNuevaReferencia
Set Ref = References.AddFromFile(PathCompletoFichero)
CrearNuevaReferencia = True
Exit_CrearNuevaReferencia:
Exit Function
Error_CrearNuevaReferencia:
MsgBox "Aviso Nº: " & Err & "..." & Err.Description & " [" & PathCompletoFichero & "]", vbCritical + vbOKOnly, "Aviso de Error"
CrearNuevaReferencia = False
Resume Exit_CrearNuevaReferencia
End Function
Cita de: quien
Cuando abro un reporte en vista previa desde un formulario Modal o Emergente, éste se sitúa detrás del formulario y no puedo verle. ¿Como presento el reporte en pantalla, por delante del formulario?
Cita de: Búho
Esto sirve para meter un report en vista previa, llamado desde un formulario MODAL. Si se hace sin mas, el Report se queda en segundo plano y no se ve.
Búho Agosto 2002
Uso:
En vez de llamar al reporte de forma habitual, lo hacemos desde esta función. Es decir, desde cualquier formulario, que deseemos lanzar un 'reporte en vista previa, con formularios modales y para evitar que dicho 'reporte se quede 'detrás' y no se vea, deberemos llamar así: OpenReport("Mireporte", etc)
Y la funcion OpenReport que hace todo esto es:
Sub OpenReport(ReportName As String, Optional View As Integer, Optional _
FilterName As String, Optional WhereCondition As String)
Dim loFormArray() As String
Dim loform As Form
Dim intCount As Integer
Dim intX As Integer
For Each loform In Forms
If loform.Visible Then
ReDim Preserve loFormArray(intCount)
loFormArray(intCount) = loform.Name
loform.Visible = False
intCount = intCount + 1
End If
Next
DoCmd.OpenReport ReportName, View, FilterName, WhereCondition
Do While IsVisible(acReport, ReportName): DoEvents: Loop
For intX = intCount - 1 To 0 Step -1
Forms(loFormArray(intX)).Visible = True
Next
End Sub
Function IsVisible(intObjType As Integer, strObjName As String) As Boolean
Dim intObjState As Integer
intObjState = SysCmd(acSysCmdGetObjectState, intObjType, strObjName)
IsVisible = intObjState And acObjStateOpen
End Function
Cita de: Happy
Tengo un formulario Cuentas, en el cual tengo un comboCliente (basado en la tabla Clientes, con dos columnas IdCliente, NombreCompañia, solo la segunda columna es visible). Cuando creo una nueva cuenta debo asignársela a algún cliente mediante ese combo, pero cuando el cliente todavía no lo he creado se activa el evento NotInList (el cliente inexistente no está en la lista del combo).
Entonces tengo éste código:
Private Sub Cliente_NotInList(NewData As String, Response As Integer)
Dim Nuevocli As Integer, entTruncarNombre As Integer, txtTítulo As String,entMsjDiálogo As Integer
Dim nuevo As String
Nuevocli = msgbox("¿Desea agregar un nuevo cliente?", vbOKCancel)
If Nuevocli = vbOK Then
nuevo = "nuevo"
DoCmd.DoMenuItem acFormBar, acEditMenu, acUndo, , acMenuVer70
DoCmd.OpenForm "clientes", acNormal, , , acAdd, , [nuevo]
Forms!clientes!NombreCompañia = NewData
Response = acDataErrContinue
End If
End Sub
Así abro el formulario Clientes, en el cual ingreso todos los datos del cliente nuevo, al abrirse el campo NombreCompañia ya estará lleno con el dato que ingresé en el combo, al terminar de escribir los datos cierro el formulario y en evento Unload tengo éste código:
Private Sub Form_Unload(Cancel As Integer)
Dim ctl As Control
If Me.OpenArgs = "nuevo" Then
Set ctl = Forms!cuentas!Cliente
DoCmd.SelectObject acForm, "cuentas"
ctl = Me!IdCliente
ctl.Requery
ctl.SetFocus
End If
End Sub
Cita de: Búho
Juan:
Me estoy haciendo un poco de lío. Se nota que estoy oxidado con Access despues de varios meses de haber dejado de forma efectiva la programación. Se notó antes de ayer con la función que me comentaste tú y Marjan.
Me planteo el siguiente caso:
Desde MDB1 deseo comprobar que en MDB2 existe un Reporte XXX
¿Como recorro los nombres de los objeto Reports de dicha MDB2?
Desde la actual, lo tengo claro con:
dbs As Object
Set dbs = Application.CurrentProject
'Aplicacion de esta, por ejemplo:
' Busca objetos AccessObject abiertos en la colección AllReports..
For Each obj In dbs.AllReports
msgbox obj.Name
Next obj
Al hilo de todo esto, tengo en mi cabeza las siguientes referencias sobre apertura y referencias a una MDB
Dim wrk As Workspace
Dim dbs1 As Database
Set wrk = DBEngine.CreateWorkspace("", "Admin", "")
Set dbs1 = wrk.OpenDatabase("RutaDestinoBase)
Esta es la primera forma. Bien...¿Cuando se emplea? ¿Cuando es conveniente abrirla así?
OTRA
Dim BaseDestino As New Access.Application
Set BaseDestino = New Access.Application
BaseDestino.OpenCurrentDatabase "Destino"
BaseDestino.CloseCurrentDatabase
Set BaseDestino = Nothing
¿Esta forma anterior cuando y por qué? ¿Diferencias y analogías con la anterior?
OTRA
Dim obj As AccessObject, dbs As Object
Set dbs = Application.CurrentProject
'Aplicacion de esta, por ejemplo:
' Busca objetos AccessObject abiertos en la colección AllReports..
For Each obj In dbs.AllReports
msgbox obj.Name
Next obj
Tengo un poco de lío al respecto. ¿Me puedes aclarar un poco el tema?
Cita de: la respuesta de Juan
Hola Francisco,
Tú dices:
"Me planteo el siguiente caso: Desde MDB1 deseo comprobar que en MDB2 existe un Reporte XXX ¿Como recorro los nombres de los objeto Reports de dicha MDB2?..."
respuesta:
Function VerReportes(BDatos As String)
Dim objAcc As New Access.Application
Dim rpt As AccessObject
objAcc.OpenCurrentDatabase BDatos
With objAcc
For Each rpt In .CurrentProject.AllReports
Debug.Print rpt.Name
Next
End With
objAcc.CloseCurrentDatabase
Set objAcc = Nothing
End Function
Tú preguntas:
"Dim wrk As Workspace
Dim dbs1 As Database
Set wrk = DBEngine.CreateWorkspace("", "Admin", "")
Set dbs1 = wrk.OpenDatabase("RutaDestinoBase)
Esta es la primera forma. Bien...¿Cuando se emplea? ¿Cuando es conveniente abrirla así?... "
Respuesta:
De esta manera estás abriendo la base de datos a través de la librería DAO y accederás a toda la jerarquía DAO (empezando con DBEngine, Workspace, Database, etc.) y todas sus propiedades, métodos y colecciones).
Tú preguntas:
"Dim BaseDestino As New Access.Application
Set BaseDestino = New Access.Application
BaseDestino.OpenCurrentDatabase "Destino"
BaseDestino.CloseCurrentDatabase
Set BaseDestino = Nothing
¿Esta forma anterior cuando y por qué? ¿Diferencias y analogías con la anterior?..."
Respuesta:
De esta otra forma abres una base de datos desde el objeto application, es decir, desde el mismo programa de Access, es como si tuvieras una ventana con la base de datos abierta (puedes tenerla o no, según quieras). De esta manera accederás a todos las colecciones, métodos, propiedades y objetos que posee el objeto application (que no son los mismos que con DAO). Tú decides en cada momento, cuál de las dos formas de abrir la base de datos te proporcionará la funcionalidad que necesitas. En el caso concreto que preguntabas es méjor acceder a la colección AllForms de CurrentProject del objeto Application, ya que contiene TODOS los informes (estén abiertos o no).
Tú preguntas:
"OTRA
Dim obj As AccessObject, dbs As Object
Set dbs = Application.CurrentProject
'Aplicacion de esta, por ejemplo:
' Busca objetos AccessObject abiertos en la colección AllReports..
For Each obj In dbs.AllReports
msgbox obj.Name
Next obj..."
Respuesta:
Aquí lo único que se diferencia de la primera es que no declaras dbs como AccessObject (que sería lo correcto), y lo declaras como Object (es decir, cualquier tipo de Objeto).
Aprovechando que tiene que ver con esto último, te comento algo que ya le comenté a McPegasus el otro día. Es un detalle tonto, pero creo que muy útil.
Imagínate que quieres hacer una rutina para rellenar un documento de Word o de Excel, desde Access. Lo normal es que empezaras declarando una variable tipo Word.Application o Excel.Application. Bien. De esta manera, podrás usar a través de esta variable la librería de objetos de Word o Excel (previa señalización en el cuadro referencias, claro). La cosa vendría a ser algo
así:
Dim appWord as New Word.Application
appWord.open Documents = "C:\doc1.doc" (o algo así, que no me acuerdo)
... ...
Pequeño truco:
Para escribir el código, hazlo como indico arriba. Será fácil y documentado por el examinador de objetos con el operador "." (punto). Una vez probado que todo funcione correctamente, rehaz la declaración de variables y añade una nueva línea al código:
Dim appWord as Object
Set appWord = CreateObject("Word.Application")
haciendo esto, puedes quitar la referencia a la librería de objetos de Word, ahorrando una referencia al programa (se abrirá una referencia implícita sólo cuando uses esa rutina), y sin embargo todo funcionará correctamente.
Creo que esta es una de las utilidades de usar variables Object (génericas). En el resto de los casos, lo mejor es declarar las variables con su tipo correcto. Puede que hayan casos en que de lo mismo, pero es más que nada como buena costumbre de programación
Saludos desde BCN
happy
Cita de: alguien que preguntó
¿Es posible importar, exportar, realizar algún cambio en un fichero MDE?.
Option Compare Database
Option Explicit
Dim Paginas As Integer
Private Sub Report_Page()
Paginas = Paginas + 1
End Sub
Private Sub Report_Close()
'Aqui llamamos a una funcion que rellene los datos para control
EscribeDatosReportes(Paginas, Me.Name)
End Sub
Function EscribeDatosReporte(NumPag as Integer, NombreRepor As String)
'Ahora debes abrir el recordset de la tabla ControlImpresion
Dim SqlF As String
Dim RstF As Recordset
SqlF = "Select * from ControlImpresion"
Set RstF = CurrentDb.OpenRecordset(SqlF, dbOpenDynaset)
With RstF
.AddNew
!Nombre_Reporte = NombreRepor
!Numero_paginas_Imprimidas= NumPag
!Nombre_Usuario_PC= DamePcUsuario()
.Update
End With
RstF.Close
End Function
Function DamePcUsuario() As String
Dim str As String
str = CurrentDb.Name '(Base de datos a consultar, esta u otra)
Dim Usuario As String
If Dir(str) <> "" Then
str = Left(str, Len(str) - 3) & "ldb"
Open str For Input As #1
Usuario = Input$(36, #1)
DamePcUsuario=Usuario
Else
DamePcUsuario=""
End If
End Function
Option Compare Database
Type cadena
cadRGB As String * 28
End Type
Type margenes
xMargenIzquierdo As Long
yMargenSuperior As Long
xMargenDerecho As Long
yMargenInferior As Long
End Type
Sub diseño(nombreinf As String) 'función para cambiar margenes en informes
Dim MargenesInf As cadena
Dim PM As margenes
Dim rpt As Report
DoCmd.OpenReport nombreinf, acViewDesign
Set rpt = Reports(nombreinf)
MargenesInf.cadRGB = rpt.PrtMip 'guardo los margenes informe
LSet PM = MargenesInf
PM.xMargenIzquierdo = 1400 ' Establece los márgenes.
PM.yMargenInferior = 600
PM.xMargenDerecho = 1400
PM.yMargenSuperior = 800
LSet MargenesInf = PM ' Actualiza la propiedad.
rpt.PrtMip = MargenesInf.cadRGB
DoCmd.Close acReport, nombreinf, acSaveYes 'guardo sin preguntar
End Sub
Function diseñoimprimir(nombreinf As String) 'función para cambiar margenes en informes
Dim MargenesInf As cadena
Dim PM As margenes
Dim rpt As Report
Set rpt = Reports(nombreinf)
MargenesInf.cadRGB = rpt.PrtMip 'guardo los margenes informe
LSet PM = MargenesInf
PM.xMargenIzquierdo = 1400 ' Establece los márgenes.
PM.yMargenInferior = 10000
PM.xMargenDerecho = 1400
PM.yMargenSuperior = 800
LSet MargenesInf = PM ' Actualiza la propiedad.
rpt.PrtMip = MargenesInf.cadRGB
' DoCmd.OpenReport nombreinf, acViewNormal
End Function