2012-01-03 14 views
8

Tengo un proyecto que básicamente el objetivo es generar Excel (Informe) comenzando el clic de un botón en Access usando VBA.VBA - Generar archivo de Excel desde Access (QueryTable)

El contenido de este informe es el resultado de una base de datos de SQL Server del Procedimiento almacenado.

la línea de error:

With MeuExcel.Worksheets(4) 
    .QueryTables.Add connection:=rs, Destination:=.Range("A2") 
End With 

lo que consigo es:

invalid procedure call or argument (erro '5') 

código completo (Editado utilizando puntas Remou Usuario):

Sub GeraPlanilhaDT() 

Dim MeuExcel As New Excel.Application 
Dim wb As New Excel.Workbook 

Set MeuExcel = CreateObject("Excel.Application") 
MeuExcel.Workbooks.Add 

MeuExcel.Visible = True 

Dim strNomeServidor, strBaseDados, strProvider, strConeccao, strStoredProcedure As String 

strNomeServidor = "m98\DES;" 
strBaseDados = "SGLD_POC;" 
strProvider = "SQLOLEDB.1;" 
strStoredProcedure = "SP_ParametrosLeads_DT" 

strConeccao = "Provider=" & strProvider & "Integrated Security=SSPI;Persist Security Info=True;Data Source=" & strNomeServidor & "Initial Catalog=" & strBaseDados 

Dim cnt As New ADODB.connection 
Dim cmd As New ADODB.command 
Dim rs As New ADODB.recordset 
Dim prm As New ADODB.parameter 

cnt.Open strConeccao 

cmd.ActiveConnection = cnt 
cmd.CommandType = adCmdStoredProc 
cmd.CommandText = strStoredProcedure 
cmd.CommandTimeout = 0 

Set prm = cmd.CreateParameter("DT", adInteger, adParamInput) 
cmd.Parameters.Append prm 
cmd.Parameters("DT").Value = InputBox("Digite o Código DT", "Código do Distribuidor") 

Set rs = cmd.Execute() 

Dim nomeWorksheetPrincipal As String 
nomeWorksheetPrincipal = "Principal" 

Worksheets.Add(After:=Worksheets(Worksheets.Count)).Name = nomeWorksheetPrincipal 



With MeuExcel.Worksheets(4) 
    .QueryTables.Add connection:=rs, Destination:=.Range("A2") 
End With 


cnt.Close 
Set rs = Nothing 
Set cmd = Nothing 
Set strNomeServidor = Nothing 
Set strBaseDados = Nothing 
Set strProvider = Nothing 

If (ActiveSheet.UsedRange.Rows.Count > 1) Then 
    FormataDadosTabela 
Else 
    MsgBox ("Não foi encontrado nenhum Distribuidor com esse DT") 
End If 


End Sub 

Lo extraño es que la el código funciona cuando se ejecuta en Excel pero no funciona en Access

+0

Vale , como tú, ahora tengo un código que funciona en Excel pero no funciona en Access. Parece que hay un problema al agregar tablas de consulta. No puedo ver por qué todavía. Me pregunto si una solución alternativa sería adecuada. Por ejemplo, ¿sería adecuado escribir los registros en una hoja de trabajo? – Fionnuala

+0

FYI: He automatizado Excel Querytables de Access durante años sin problemas, aunque con datos de Access como origen. Sin embargo, no lo he probado en Office 2010. –

+0

@Rachel ¿Tal vez podría publicar algún código de acceso que funcione? – Fionnuala

Respuesta

5

En Access, es necesario como prefijo para los objetos de aplicación de Excel con la instancia de la aplicación Excel, por ejemplo:

With MeuExcel.Worksheets(4).QueryTables.Add(_ 
    connection:=recordset, _ 
    Destination:=Range("A2")) 
End With 

Por otra parte, a menos que tenga una referencia a la biblioteca de Excel, ypu tendrá que proporcionar el valor para la construcción -en constantes de Excel.

Es una muy mala idea usar el nombre de los objetos para las variables. No diga:

Dim recordset As recordset 
Set recordset = New recordset 

Digamos, por ejemplo:

Dim rs As recordset 

O mucho mejor:

Dim rs As New ADODB.Recordset 

Si usted tiene una referencia adecuada. A continuación, puede omitir CreateObject.

EDITAR

el proveedor debe ser el proveedor OLEDB de acceso 10, tal como se utiliza para unir los conjuntos de registros. Esto funciona para mí para crear una tabla de datos a través de Access utilizando SQL Server:

strConnect = "Provider=Microsoft.Access.OLEDB.10.0;Persist Security Info=True;" _ 
& "Data Source=XYZ\SQLEXPRESS;Integrated Security=SSPI;" _ 
& "Initial Catalog=TestDB;Data Provider=SQLOLEDB.1" 
+0

Gracias por las sugerencias, pero no resolvió mi problema – Predoff

4

Fwiw, dos cosas sobresalen:

  1. Como @Remou señaló, tienen que ser calificado referencias Excel. Actualmente, Range("A2") no está calificado. Al ejecutar el código en Excel, se supone ActiveSheet. Sin embargo, cuando se ejecuta desde otra aplicación, esa aplicación buscará un método o propiedad en su propia biblioteca llamada Range, que le dará ese error en Microsoft Access.No hay ningún código en el bloque With, por lo que puede eliminar las palabras clave With y End With; al hacer esto también quitar el exterior(), así:

wb.Worksheets(4).QueryTables.Add Connection:=rs, Destination:=wb.Worksheets(4).Range("A2")

Como alternativa, desplace el bloque de With al nivel Worksheet:

With wb.Worksheets(4) 
    .QueryTables.Add Connection:=rs, Destination:=.Range("A2") 
End With 

Update- Acceso a la muestra de Excel

Este código de ejemplo automatiza Excel desde Access, crea un nuevo libro de trabajo y agrega un Querytable a la primera hoja. La fuente de datos es una tabla de acceso. Esta Oficina se ejecuta en 2007.

Public Sub ExportToExcel() 
    Dim appXL As Excel.Application 
    Dim wbk As Excel.Workbook 
    Dim wst As Excel.Worksheet 
    Dim cn As ADODB.Connection 
    Dim rs As ADODB.Recordset 

    Set appXL = CreateObject("Excel.Application") 
    appXL.Visible = True 
    Set wbk = appXL.Workbooks.Add 
    Set wst = wbk.Worksheets(1) 

    Set cn = CurrentProject.AccessConnection 
    Set rs = New ADODB.Recordset 
    With rs 
    Set .ActiveConnection = cn 
    .Source = "SELECT * FROM tblTemp" 
    .Open 
    End With 

    With wst 
    .QueryTables.Add Connection:=rs, Destination:=.Range("A1") 
    .QueryTables(1).Refresh 
    End With 

End Sub 
+0

llamada o argumento de procedimiento no válido – Predoff

+0

Gracias, pero no resolvió mi problema:/ – Predoff

+0

@Predoff Modifiqué mi ejemplo para sustituir el objeto '' Workbook'' por '' Excel Aplicación'' objeto. No estoy seguro si esto resolverá su problema, pero es más correcto. –

0

Usted no dice qué versión de Office, pero en Excel 2007/10 un QueryTable es una propiedad de un ListObject lo que el código sería:

With MeuExcel.Worksheets.ListObjects.Add(Connection:=rs, Destination:=Range("A2")).QueryTable 
+2

Después de volver a leer la pregunta, me doy cuenta de que este no es el problema, ya que tiene un error de tiempo de ejecución. Creo que @RachelHettinger (como de costumbre) ha dado en el clavo. –

+0

Argumento con nombre no encontrado – Predoff