简体   繁体   中英

New Issue, defining Fields/RecordsWAS Why can't I use DAO in VBA Program written in Excel 2013

Please refer to latest comment by me as I have one more follow up question about column names/reassigning header row. Thanks! KDL!


OK, I am able to Open the "database" so I can set up queries of recordsets using DAO, and I have figured out how to define a named range so I have a variable that can act as the "Field Name". I am having an issue with VBA code to insert that Named range into the SELECT SQL statement. This is the relevant section of code that I am still having a problem with

BEGIN CODE '********************************** Dim db as DAO.Database Dim rst as DAO.Recordset

Dim refRngItemSKU As Excel.Range Dim LastRowAsIngeger as Integer Dim INVENTORYTABLE as String Dim strSelectRS as String

' ************************

LastRowAsInteger = 1764 'Value set in code for now, will be formula later to make dynamic

Set refRngItemSKU = ThisWorkbook.Worksheets("Vendor Inventory").Range("A11:A" & LastRowAsInteger)

' ******* NOTE when I insert refRngItemSKU.select the correct range of cells are selected **********

INVENTORYTABLE = "D:\\My Documents\\Leavers Switches And More\\INVENTORY\\COLLECTIONS AND DISTRIBUTOR INVENTORY\\Model Train Inventory - Updated 6-7-2017.xlsm"

Set db = DBEngine.OpenDatabase(INVENTORYTABLE, False, False, "Excel 12.0;")

strSelectRS = "SELECT * FROM [Vendor Inventory$] WHERE [refrngitemsku$] IS NOT NULL"

Set rst = db.OpenRecordset(strSelectRS)

'********************************************** END OF CODE

Now everything up to the last line of code works. When it reaches the "Set rst" line, Error 3061 comes up. The error states "Too Few Parameters. Expected 1". When I am in Debug mode, I notice the "refrngitemsku" variable is not returning a value in the "strSelectRS" string where the actual value should be showing up. So any help in correcting the Syntax so I can return a value, ie. the actual range of cells that the refrngItemSKU variable is supposed to return. Thank you again. Sorry for having to edit my Question, but the comment section does not allow for enough letters to type all this out. To the moderators, I appreciate your patience with my posts. But I am desperate for answers, and so far, this forum is the only one that have been willing to answer my questions! Thanks again.

Ken L.


POSTED EARLIER GOOD NEWS! Thanks to the suggestion of using ACEDAO.DLL that seems to have resolved the first problem, but a new one has crept up. I can't find a way to use DAO, in Excel 2013-64, using SQL to query the various tables. It seems I can not define "Fields" and "Records" whereby the Columns are the "Fields" and the Rows are the "Records". Though when I do a recordcount on the record set, it shows the total number of rows that have data on them. But when I try to identify a column (Ie Field) to set conditions on which records to select, I get syntax errors. Any help would be much appreciated, and thanks again to all of the posts, they all have been helpful as it caused me to google specific terms to find solutions to my current project! THANK YOU THANK YOU THANK YOU!

Ken L ORIGINAL POST: I have searched using google to find a specific answer with no luck. I keep getting error code 429 when trying to use DAO language "OpenDatabase" so I can use SQL Language to search various worksheets in one Excel 2013 Workbook. I am running Windows 7-64 and Office 2013 64-bit. From what I have read, it would appear DAO is not supported anymore by Microsoft, and even ADO doesn't look like it is looked favorably by the folks at Microsoft anymore. I really don't care if I can't use DAO anymore as long as if there is a method where I can use similar functionality to find specific records based on specific criteria, amend certain records, create other records, and move amongst records (ie .movefirst, .movelast, etc.). If there is a different VBA language that is usable for 64 bit versions of my software, I will learn it.

I rather not use the workbook, worksheet functions and using IF-THEN statements going through the entire table trying to find certain "records" that match the criteria I am looking for. It works, but its tedious and I much rather use SQL type language.

I realize using MS Access would be more appropriate, but I prefer using the Spreadsheet format. What I am trying to do is write a VBA program that converts certain cell values into a certain format to be converted to a csv file to upload to a website for my web-store. The file is my inventory sheet, with tons of calculations/formulas in it. I rather not use MS Access if I don't have to.

Thank you for any help that can be provided!

Thanks.

Ken L.

You can use ADO:

Dim conn As New ADODB.Connection
conn.Open("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=c:\myFolder\myOldExcelFile.xls;Extended Properties=""Excel 8.0;HDR=YES"";")

Include a reference to Microsoft Office 15.0 Access database engine Object Library (ie use AceDAO instead of Jet DAO; drop any reference to DAO 3.6)

OpenDatabase([filepath], [Exclusive], [Read only], [Connect string])

OpenDatabase([filepath], False, True, "Excel 12.0 Xml;HDR=yes;")

Excel 12.0 Xml = .xlsx

https://msdn.microsoft.com/en-us/library/office/ff965871(v=office.14).aspx#DataProgrammingWithAccess2010_DirectDAOExample

ADDED:

OpenRecordset("SQL statement", ...)

In SQL statement:

  • Tables can be SheetName$ or SheetName$-plus-range-specifier or RangeName

  • Add a $ onto the end of sheet names (eg Sheet1$)

  • Tables (Excel lists) probably aren't recognized; you may need to explicitly define an overlapping range name using cell notation (eg a1:b10)

SQL example (you can enclose Table and Field names in brackets [] to escape characters that may conflict, eg spaces):

SELECT * FROM [Sheet1$] WHERE ([Field Name in Brackets] = SomeNumericValue)
SELECT * FROM [Sheet1$] WHERE ([Field Name in Brackets] = 'SomeTextValueInSingleQuote')
SELECT * FROM [Sheet1$] WHERE ([Field Name in Brackets] = #SomeDateInHashTags#)

Syntax help: https://msdn.microsoft.com/EN-US/library/office/dn123881.aspx

ADDED 2:

  • you can't define a range as a variable in your VBA and then pass along that variable name in the SQL statement; the range has to be defined as a named range in the Excel workbook itself (eg using the Name Manager dialog in Excel or VBA code), then on the database engine side it can look up that name from the SQL statement text against available table names;

  • you can use VBA to create a defined/stored named range using something like:

ActiveWorkBook.Names.Add(Name:= "MyRangeForSQL", RefersTo:= "=A11:E1764")

  • if no field names in the first row, then you need to change the connect string to indicate no header row by including "HDR=No;" ; Ace/Jet will then create some default field names: "F1" - first column, "F2" - second column, "F3" -etc. eg

    strSelectRS = "SELECT * FROM [MyRangeForSQL] WHERE [F1] IS NOT NULL"

ADDED 3:

  • you can always alias the (table and) field names in the SQL statement: [FieldName] AS [FieldNameAlias]

strSelectRS = "SELECT [F1] As [Sku], [F2] As [Quantity], [F3] As [Price] FROM [MyRangeForSQL] WHERE [Sku] IS NOT NULL"

  • should probably mark this question as answered, getting outside of original scope; good luck

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM