2009-05-27 28 views
15

Todo lo que intento hacer es tomar un rango estándar en una hoja de Excel (es decir, un rango con nombre, o incluso A1: F100) y ejecutar algunas consultas sql y devolver un conjunto de registros que pueda pasar en VBA código, o incluso simplemente pegar en otra hoja en el mismo libro de trabajo.¿Cómo puedo ejecutar sentencias de SQL en un rango con nombre dentro de una hoja de Excel?

El uso de ADODB fue una idea, pero ¿cómo podría configurar la conexión para apuntar a un rango dentro del libro actual?

Lo sé antes de haber hecho uso del asistente de consultas de Microsoft, que no era ideal, pero funcionaría. Parece que no puedo hacer referencia a un rango dentro de la hoja, solo a otros archivos de Excel.


Aquí está la función que me queda. Cuando lo ejecuto varias veces, mi excel falla con el mensaje de error habitual de falta de recursos. Eliminé esta función de mi hoja de cálculo y todo se ejecuta sin interrupciones varias veces, por lo que definitivamente es causado por el código aquí.

He limpiado todos los objetos (¿correctamente?). ¿Alguien tiene alguna idea de lo que podría estar yendo mal? ¿Podría haber algo en la cadena de conexión que podría modificarse, o podría ser algo relacionado con la variante que se devuelve desde el método GetRows?

Estoy usando MS ADO 2.8, y también he probado 2.5 con el mismo comportamiento.

Function getTimeBuckets() As Collection 

Dim strFile As String 
Dim strCon As String 
Dim strSQL As String 
Dim dateRows As Variant 
Dim i As Integer 
Dim today As Date 

Dim cn As ADODB.Connection 
Dim rs As ADODB.Recordset 

Set cn = CreateObject("ADODB.Connection") 
Set rs = CreateObject("ADODB.Recordset") 
Set getTimeBuckets = New Collection 

strFile = ThisWorkbook.FullName 
strCon = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & strFile _ 
    & ";Extended Properties=""Excel 8.0;HDR=Yes;IMEX=1"";" 
cn.Open strCon 

strSQL = "SELECT DISTINCT(Expiration) FROM [PositionSummaryTable] where [Instrument Type] = 'LSTOPT'" 

rs.Open strSQL, cn 


dateRows = rs.GetRows 
rs.Close 

'today = Date 
today = "6-may-2009" 

For i = 1 To UBound(dateRows, 2) 
    If (dateRows(0, i) >= today) Then 
     getTimeBuckets.Add (dateRows(0, i)) 
    End If 
Next i 

Set dateRows = Nothing 
Set cn = Nothing 
Set rs = Nothing 
End Function 

Respuesta

16

Puede simplemente usar el nombre.

Dim cn As ADODB.Connection 
Dim rs As ADODB.Recordset 

strFile = Workbooks(1).FullName 
strCon = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & strFile _ 
    & ";Extended Properties=""Excel 8.0;HDR=Yes;IMEX=1"";" 

Set cn = CreateObject("ADODB.Connection") 
Set rs = CreateObject("ADODB.Recordset") 

cn.Open strCon 

''Pick one: 
strSQL = "SELECT * FROM DataTable" ''Named range 
strSQL = "SELECT * FROM [Sheet1$A1:E346]" ''Range 

rs.Open strSQL, cn 

Debug.Print rs.GetString 

En respuesta a la pregunta parte 2

Me he dado cuenta de que sólo desea que los registros de hoy en día, por lo que debe ser capaz de modificar el SQL para:

strSQL = "SELECT DISTINCT(Expiration) FROM [PositionSummaryTable] " _ 
& "where [Instrument Type] = 'LSTOPT' AND [Expiration]=#" _ 
& Format(Date(),"yyyy/mm/dd") & "#" 

no ha cerrado la conexión:

cn.Close 

Y luego

Set rs=Nothing 
Set cn=Nothing 
+0

Gracias, funciona genial. Debo haber tenido otra cosa incorrecta (ver el comentario anterior), que me hizo pensar que tenía que hacer algo diferente con la cadena de conexión. – cOrOllArY

+0

Puede tener problemas con ADO si no ha guardado. – Fionnuala

+0

Todo funciona perfectamente, pero hay algún tipo de pérdida de memoria. Voy a publicar la función a continuación, ya que es demasiado tiempo para el comentario. – cOrOllArY

0

Usted encontrará todo lo que necesita a continuación:

primer enlace es para VB.NET, enlaces 2 - 6 son para VBA.

One

Two

Three

Four

Five

Six

Encontrado todo en google, aproximadamente 2 - 4 minutos.

+1

Hola praavDa Me pareció que todos estos mismos enlaces. Estoy buscando una manera de hacerlo desde el archivo que tengo abierto, no un documento separado de Excel. Todo lo que necesito es cómo configurar la cadena de conexión para que haga referencia al documento actual desde el que está llamando al código VBA, o si esto es posible. Gracias, Mike – cOrOllArY

+0

Hola Mike. Por lo que entiendo, el documento al que se hace referencia es el que se hace referencia como origen de datos en. Dim stCon As String stCon = "Proveedor = Microsoft.Jet.OLEDB.4.0;" _ & "Origen de datos = c: \ VBExtreme.xls;" _ & "Propiedades extendidas =" "Excel 8.0; HDR = YES" ";" Primeros camino del libro activo se puede lograr con: Dim wb Como libro de trabajo el valor de WB = ActiveWorkbook path = a.path & "\" & a.Name Con el conjunto de ruta, la cadena con la derecha le gustaría como: Dim stCon como cadena stCon = "Proveedor = Microsoft.Jet.OLEDB.4.0;" _ & "Data Source =" & path _ & "Extended Properties =" "Excel 8.0; HDR = YES" ";" – praavDa

+0

Y si no me equivoco, entonces la última parte de la cadena es la versión de la biblioteca que tiene en herramientas/menú Referencias en el editor VBA en Excel (probablemente 11 para la versión Excel 2003 o 12 para 2007). Perdón por el formateo en el último, no sabía, que no podía usar saltos de línea en los comentarios :) – praavDa

0

No sé acerca de VBA, pero hay código en línea en Delphi y C# que utiliza el formato

SELECT * FROM [SheetName$A1:B2] 

¿Lo has probado?

+1

¿cómo ejecutarías una declaración como esta en VBA? – cOrOllArY

1

¿Qué le parece usar el LIKE clause?

He intentado utilizar:

select * from [PES$] where PID_TAG like '*5400001' 

sin éxito ....

esto funciona:

select * from [PES$] where PID_TAG = 'PIT5400001' 

pero esto no es lo que quiero.

EDITAR

hummm .... tenemos que cambiar comodines para trabajar ... no utilizan *, el uso%

0

Si está utilizando PowerShell, $ es un carácter interno . usar `$

por ejemplo:

"Select * from [VM`$A3:F30]" 
Cuestiones relacionadas