tags:

views:

1261

answers:

5

This is a very simple question which I am pulling my hair out with. No amount of web searching seems to help!

All I am trying to do is take a standard range on an excel sheet (i.e. a named range, or even A1:F100), and run some sql queries on it, and return a recordset that I can either step through in VBA code, or even just paste into some other sheet in the same workbook.

Using ADODB was one thought, but how could I setup the connectionstring to point to some range within the current workbook?

I know before I have made use of the Microsoft query wizard, which was not ideal, but would work. I can't seem to get this to refer to a range within the sheet, only other excel files.

Can anyone please help me before I quit programming forever!

Your help is much appreciated.

Mike

+1  A: 

Hi,

You will find all You need below:

First link is for VB.NET, links 2 - 6 are for VBA.

One

Two

Three

Four

Five

Six

Found all in google, about 2 - 4 minutes.

praavDa
Hi praavDaI found all these same links. I am looking for a way to do it from the file I have open, not a seperate excel document. All I need is how to configure the connection string so it references the current document where you are calling the VBA code from, or if this is even possible.Thanks,Mike
Mike
Hi Mike. From what I understand, the referenced document is the one referenced as data source in. Dim stCon As String stCon = "Provider=Microsoft.Jet.OLEDB.4.0;" _ " _ HDR=YES"";" Getting path of active workbook can be acheived with:Dim wb As WorkbookSet wb = ActiveWorkbookpath = a.path " _ HDR=YES"";"
praavDa
And if I am not mistaken, then last part of the string is the version of the library You have in tools / References menu in VBA editor in Excel (most probably 11 for Excel 2003 version or 12 for 2007 one). Sorry for the formatting in last one, I didn't knew, that I couldn't use line breaks in comments:)
praavDa
Cool, thaks, i got it working. Not even sure what was wrong, but I thought that it wasn't working because I was referring to the file I was working in. So I created a seperate test file and pointed my conn string to that, got that working, and then switched the file name, and it worked...so not sure what I did wrong the first time. Thanks for the help!
Mike
Wathcing the task manager, the line thats taking the memory that is never released is rs.Open.
Mike
Maybe rs needs to be closed in the end?
praavDa
A: 

I don't know about VBA, but there are code online in Delphi and C# that uses the format

SELECT * FROM [SheetName$A1:B2]

Have you tried it?

eed3si9n
how would you execute a statement like this in VBA?
Mike
+3  A: 

You can just use the name.

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

In response to question part 2

I notice that you only want today's records, so you should be able to modify the sql to:

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

You have not closed the connection:

cn.Close

And then

 Set rs=Nothing
 Set cn=Nothing
Remou
Thanks, works great. I must have had something else wrong (see above comment), which made me think you had to do something different with the connection string.
Mike
You can run into problems with ADO if you have not saved.
Remou
It all works perfectly, but there is some kind of memory leak going on.I will post the function below as it's too long for the comment.
Mike
Even afer closing the connection, that function still holds on to a large chunk of memory. There is no way to force garbage collection in VBA like there is in C# is there? (i doubt this will work anyway, but it would be worth a try) It is definitely wanting to old on to some object in that function :(
Mike
Looking at the task manager, it is definitely the call rs.Open which is grabbing the memory, and never letting go.
Mike
There is a KB: http://support.microsoft.com/kb/319998 BUG: Memory leak occurs when you query an open Excel worksheet by using ActiveX Data Objects (ADO)
Remou
Thanks! At least I know now I'm not doing something stupid. I kinda gave ADO to much credit thinking: "There can't possibly be such a large bug in here, everyone uses ADO." But I suppose not many people use it to refer to an open file... Thanks again for all the help :).
Mike
A: 

Here is the function I am left with. When I run it a few times my excel crashes with the usual out of resources error message. I have removed this function from my spreadsheet, and everything runs seamlessly multiple times, thus it is definitely caused by the code here.

I have cleaned up all the objects (correctly?). Does anyone have any ideas what could be going wrong? Could there be something in the connection string that could be tweaked, or could it be something to do with the variant that is returned from the GetRows method?

I am using MS ADO 2.8, and have also tried 2.5 with the same behaviour.

Many thanks for all your help!

-Mike

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
Mike
I have a couple of quick thoughts to my post.
Remou
A: 
Eduardo