Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

( I have edited this questions, see below ) I have searched on here and google but I still cannot solve my issue. I am trying to use an excel's named range equivalent in my .vbs file. This below works in VBA in excel but I cannot get it to work in a VBS file.

ThisWorkbook.Sheets(1).Range("A1:AX" & Range("AX" & Rows.Count).End(xlUp).Row).Name = "DATA"
strSql = "SELECT * FROM DATA"

So, I have tried different variations of referencing to DATA, but with no luck.
This is what I have now:

' ws = worksheet, wb = workbook
Set rng = ws.Range("B" & i+1 & ":AX" & j-1)

Call createAndInsertRecordSet(wb.FullName, rng)

Sub CreateAndInsertRecordSet(ByVal fullname, ByRef rng)

    ' Create objects
    Dim cn, rs, strCon, strSql, cn2
    rng = "DATA"    
    strCon = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & fullname & ";Extended Properties=""Excel 8.0;HDR=NO;IMEX=1"";"
    strSql = "SELECT * FROM DATA"

And I have tried different variations like taking parameter ByVal, using rng instead of DATA (string type), "SELECT * FROM " & rng, etc..

The error msg when running:

Microsoft (R) Windows Script Host Version 5.8 Copyright (C) Microsoft Corporation. All rights reserved.

C:\Users\admin\Desktop\UpdateSourceTbl.vbs(119, 5) Microsoft JET Databas e Engine: The Microsoft Jet database engine could not find the object 'DATA'. M ake sure the object exists and that you spell its name and the path name correctly.

Any help greatly appreciated!

EDIT:
The whole point of doing this using VBScript its to update a database with a single click on one icon ( ill have a script on the server that will run file automatically )
Below is a sample of what the Excel file looks like. I cant modify the design of the file. Also, I do not want to create a 'copy' that I could design as a relational database ( bad efficiency ). I just want to stick to this design, ok? :) note the empty rows between records, different lengths of each records. I am only interested in uploading a few columns though (date,wo,operator,operation,start time, check time, both amounts of parts, breaks - the rest can be calculated) -. So I thought of creating a recordset for each record ( record = data in between spaces in rows ) and exclusively choosing only recordset.Fields(n) that I want.
sample data
Code: ( .vbs ) So, I am opening the excel file and looping through all rows on all worksheets. finding first and last row for each record, and trying to dynamically name found Range and upload it to my database. I have taken out lines here, and there to make the code as simple as required to understand what im doing.

Option Explicit

'Declare 
Dim xl, wb, fPath, rng

'Path to file
fPath = "C:\Users\admin\Desktop\Source\source2.xlsm"

'Process
Call OpenFile (xl, wb, fPath)
Call UpdateSourceTbl (wb)
Call CloseFile (xl, wb)

'Open and link excel file
Sub OpenFile(ByRef xl, ByRef wb, ByVal fPath)

    'create an excel instance
    Set xl = CreateObject("Excel.Application")
    xl.Visible = False
    'open workbook
    Set wb = xl.Workbooks.Open(fPath)  

End Sub

'Update Source Table in the db
Sub UpdateSourceTbl(ByRef wb) 

    'declare locals
    Dim ws, lastRow, i

    'iterate through all wSheets
    'for i = 1 to wb.Sheets.Count-4 
    for i = 1 to 1
        'link to sheet
        Set ws = wb.Sheets(i)
        'get last row used in the active sheet
        lastRow = ws.UsedRange.Rows.Count
        'run engine
        if lastRow >= 2 then Call ProcEachRst(ws, lastRow)
        Set ws = Nothing
    next

End Sub 

'Proccess Each Recordset
Sub ProcEachRst(ByRef ws, byVal lastRow)
    dim i, j
    'for i = 2 to lastRow
    for i = 2 to 30 
        'first and -one line- record
        if i = 2 and ws.Range("B" & i+1).Value = "" then

            ' named range
            Set rng = ws.Range("B2:AX2")
            ws.Range("B2:AX2") = "MyRange"
            Call createAndInsertRecordSet(wb.FullName)

        elseIf (i = 2 and ws.Range("B" & i+1).Value <> "" ) or (ws.Range("B" & i).Value = "" and ws.Range("B" & i+1).Value <> "") then
            j = i + 1
            do until ws.Range("B" & j).Value = "" 
                j = j + 1
            loop
            if i = 2 then
                'always starts at row 2
                Set rng = ws.Range("B2:AX" & j-1)
                ws.Range("B2:AX" & j-1 & ") = "MyRange"
                Call createAndInsertRecordSet(wb.FullName)
            else
                'add 1 to i - first record ( i > 2 )
                Set rng = ws.Range("B" & i+1 & ":AX" & j-1)
                ws.Range("B" & i+1 & ":AX" & j-1 & ") = "MyRange"
                Call createAndInsertRecordSet(wb.FullName)
            end if
        end if
        ' release rng ref
        set rng = Nothing
    next
End Sub

'Close and unlink excel file
Sub CloseFile(ByRef xl, ByRef wb)

    xl.Quit 
    Set wb = Nothing
    Set xl = Nothing

End Sub


' SQL Server 2008 connection
Sub CreateAndInsertRecordSet(ByVal fullname)

    ' Create objects
    Dim cn, rs, strCon, strSql, cn2

    strCon = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & fullname & ";Extended Properties=""Excel 8.0;HDR=NO;IMEX=1"";"
    strSql = "SELECT * FROM myRange"

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

    ' Connect to workbook
    cn.Open strCon
    ' Execute sql query on open workbook
    rs.Open strSql, cn

    ' Execute new query
    '   *Inserts Recordset to db
    Set cn2 = CreateObject("ADODB.Connection")

    With cn2
        .CursorLocation = adUseClient
        .Open "Driver={SQL Server};Server=SERVERPATH; Database=prod_rep; UID=ADMIN; PWD=PASSWORD"
        .CommandTimeout = 0
        rs.MoveFirst
        Do While Not rs.EOF
            .Execute "INSERT INTO prod_rep.dbo.report ( [date], [wo], [operator], [operation], [start time], [check time], [amountST], [amountCHK] ) VALUES ('" & rs.Fields(0) & "', '" & rs.Fields(3) & "', '" & rs.Fields(9) & "', " & rs.Fields(12) & "', " & rs.Fields(21) & "', " & rs.Fields(24) & "', " & rs.Fields(30) & "', " & rs.Fields(33) & "', " & rs.Fields(45) & ")"
            rs.MoveNext
            Loop
    End With

    ' Close connections
    ' Unlink
    rs.Close
    Set rs = Nothing
    cn.Close
    Set cn = Nothing
    cn2.Close
    Set cn2 = Nothing
End Sub

EDIT2: I used 2 parameters with row numbers, may not be the best solution - but it works! and i cant see nothing wrong with it to be fair

Call createAndInsertRecordSet(wb.FullName, ws.Name, i+1, j-1)
Sub CreateAndInsertRecordSet(ByVal fullname, ByVal wsName, ByVal stRow, byVal enRow )
strSql = "SELECT * FROM [" & wsName & "$B" & stRow & ":AX" & enRow & "]"
share|improve this question
If you ran those first two lines exactly as written in VBScript then it will not work, because the constant xlUp is not defined outside of Excel. You need to replace it with its actual value (which you can find using the object browser in excel (F2 in the VB Editor). It would help to update your question with the complete VBscript you're using. – Tim Williams Apr 5 at 16:22
Tim, I can see where you going with it - can you please explain a little bit more how could i use ( overwrite ) the Excel.Direction class, or how to declare xlUp as a Constant ( it cant as simple as declaring constant with a value of Const xlUp = -4162 (&HFFFFEFBE) ? ) – mehow Apr 8 at 7:15
I added another suggestion in my answer below, one problem is that your code to create the named range doesn't work, and even if it did, JET can't see it unless the workbook is saved, that's why you need a Schema File (Schema.ini) – Philip Apr 8 at 8:42
1  
Yes - you just declare a constant, or use the value directly in your code. – Tim Williams Apr 8 at 16:18

1 Answer

EDIT: Please change the line

ws.Range("B2:AX2") = "MyRange"

with

activeworkbook.Names.Add Name:="myRange", RefersTo:="B2:AX2"

I think that will properly create the name DATA.

Unfortunately it still may not work without SAVING THE WORKBOOK as JET OLE DB Provider/DB Engine works on a file on Disk, not in memory

Here I think you may need to dynamically create a Schema.ini file to define the columns you want.

Remember that JET expects to see data in columns, so if there are columns to be skipped, then perhaps they need to be defined in a Schema file even if it means you have to dynamically write the schema at runtime

Another point here, the error you are geeting can be checked/debugged by running the query using MS Query in MS Excel to see if the JET DB Engine can see the DATA range

you need to read up on how to access Excel data use ADO/OLE DB

first, to find out how to reference your DATA named range, open MS Query in Excel and query the sheet

see this site: Use MS Query to Treat Excel As a Relational Data Source

see the below links:

remember, what works in Excel VBA inside Excel's VB Editor will not work the same way in VBScript as there is no Type declaration, and no Intellisense.

share|improve this answer
Philip, Thanks for the links. I have read the articles, however, unfortunately, I have not found it very useful. Most of it its something I have already knew, or something that does not really apply to my problem. I cannot use MS Query because lets say the file im opening is going to change every day and the structure of the file isnt any close to a RDB like design. I have to iterate through the file and find the ranges. I will update my original post with examples. Thanks for your answer however, I cannot mark it as a good answer, sorry – mehow Apr 8 at 7:11
What I mean is, use MS Query inside MS Excel (from the Data Menu)to run the Query SELECT * FROM myRange once to ensure the range is identified and found by the Jet DB Engine – Philip Apr 8 at 8:21
Its still throwing Expected Statement error. I have found a solution. Let me post. sometimes the simplest approach will do the job... screw named ranges :P – mehow Apr 8 at 9:23
@mehow - EXACTLY:) Screw those darned named ranges... use the worksheet name with ` and ! – Philip Apr 8 at 9:52

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.