OpenSchema(adSchemaColumns) for table with hyphens in name - excel

I'm reading some Excel data using ADO, and want to acquire some OpenSchema column values.
My connection string (which successfully opens the connection) is:
Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:[my
path].xlsx;Extended Properties="Excel 12.0 Xml;HDR=YES;IMEX=1;";
I can happily open the AdSchemaTables recordset and get the table name:
Set tablesRs = conn.OpenSchema(AD_SCHEMA_TABLES)
Do While Not tablesRs.EOF
tbl = tablesRs.Fields("TABLE_NAME")
/../
Loop
And for a table with a name like Sheet1$, I can also happily read my column data:
Set colsRs = conn.OpenSchema(AD_SCHEMA_COLUMNS, Array(Empty, Empty, tbl))
My problem is that the name of one of the sheets contains hyphens, eg "16-11-2018" and this seems to throw a 3251 error. I've tried with and without inverted commas "'16-11-2018'" and square brackets "[16-11-2018]", but the former throws 3251 and the latter returns an empty recordset.
I know the data is good because if I copy the sheet to a different workbook with a generic sheet name, my code works fine. So I'm assuming my problem is related to that sheet name.
Is there a way of dealing with this sheet name?

Enclose it in single quotes, so you are effectively looking to use:
Array(Empty, Empty, "'16-11-2018$'")
as the second argument.

Related

How do I preserve the leading zeros in a user entered field with excel vba

I am a newbie working on my first excel vba application. One of my user forms has a text box that the user enters data into. The data is likely to be a number that has leading zeros. I am placing the input in a string and trying to format it as text but both things I tried to not work. Any help would be appreciated.
Here are the two things I tried after search on line for how to format text in VBA code
txtString.NumberFormat = "#"
txtString.Value = Format(txtString.Value,"'0")
Thanks for any help.
More detailed question:
My application has 15 user forms and a workbook with 19 sheets in it. The first 5 sheets are excel worksheets that are used as databases. There are 2 worksheets that are inventory databases (account for 2 different types of inventory), there is a worksheet that tracks orders, there is a work sheet that tracks test results for products in inventory, and there is a worksheet to track the label information that must go on order. When the order is generated the user enters a package tag which is likely to be a number with leading zeros. The entry with leading zeros is stored in the orders database correctly. A different user from generates the label information that must go on the product. To do this the application displays orders that need labels and then when the user selects the order they want to generate the label the application searches the order database to get info to put on label and places this in a variable within the module associated with the generate label user form. It gets data in this fashion from each of the other databases to have all of the label information together. It then writes these variables to the database that has the label info in it. When it does this the leading zero get stripped off. I done several searches to find ways to do this and I have tried many of them and cannot seem to get any to work. I was hoping to fix this with the format method because I have to use it with other things I pull from the database like %s. The stripping of the leading zeros occurs when I store the value in the worksheet that has the label info. It does not matter if I set the cell in the label worksheet from a variable or directly from the orders workbook the leading zeros get stripped off.
Thanks!
Assuming your input is a string. Converts string to value you can work with. Calculates how many zeros to precede with in case it is not consistent.
Sub PrecedingZeros()
Dim strng As String
Dim lng As Integer
Dim fmt As String
Dim i As Integer
With Selection
strng = .Value
lng = Len(strng)
.NumberFormat = "#"
fmt = "0"
If lng >= 2 Then
For i = 2 To lng
fmt = fmt + "0"
Next i
End If
.NumberFormat = fmt
.Value = CSng(strng)
End With
End Sub
All
Thanks for your help. I ended up prepending a "'" to the text string every time I set my internal variable and that kept the leading zeros in place. This worked so I dropped the format idea.
Thanks again!
Bruce

Searching for Specific Column Headers in Excel File - Runtime Error 91

I am attempting to write some excel vba code that will process the content of certain columns of data. Given the worksheet has some level of dynamic change (columns added and removed from time to time), I want my code to "find" the specific columns by their header names, and ultimately return the column number. My File has roughly 50 columns.
The problem is this: My code works just fine to find many of the columns (headers) I am interested in returning the column index, but some of the columns "while clearly existing", will return Nothing and thus, throws the runtime 91 error.
I can say, without a doubt that when I execute the .find, that truly, the columns DO exist (like the Comments column). I can randomly change the failing hdr search column to a different header name, passing it to the function in the code and some columns are found just fine, and other, cause the runtime error. I have checked the "failing" headers for special characters, blanks, LF's etc. No luck. Even tried re-ordering the 4 rows using FindColHdrNum function. Again, no luck.
Was hoping fresh eyes may provide answer. Simplified code is below which is triggered by a button on main excel worksheet. I have not worked with functions much in VBA, and even where the function does not generate the Runtime Error, it is not returning the column value, but this is a secondary problem I can work on once I get the find code not blowing up (returning 0).
Sub Button119_Click()
Dim L4RankCol As Integer
Dim DecomDriverCol As Integer
Dim SupTermImpactYrCol As Integer
Dim Comments As Integer
Dim L3RankCol As Integer
L4RankCol = FindColHdrNum("L4 Rank") '<-- This works
DecomDriverCol = FindColHdrNum("Decom Driver") '<-- This works
SupTermImpactYrCol = FindColHdrNum("Support Termination Impact Yr") '<-- This works
Comments = FindColHdrNum("Comments") '<-- This does not work
End Sub
Function FindColHdrNum(strHdr As String) As Integer
Dim rngAddress As Range
Set rngAddress = Range("Headers").Find(strHdr)
FindColumnHdrNum = rngAddress.Column '<--runtime error is caused by Nothing returned
End Function
Issue turns out to be a spurious line feed that was embedded in the header. It was strange as I kept re-typing it, but of course, I would always start at the "first letter" of the "comment" header, when in fact, the character preceded that. Thanks to all, for the help!
The name of your function is FindColHdrNum but you wrote this into the function:
FindColumnHdrNum = rngAddress.Column
Instead of:
FindColHdrNum = rngAddress.Column

How to trim collection fields name or column name

I have three columns (First Name , Last Name and phone Number) in my collection that I got from excel using "copy as collection" functionality of Excel VBO.
Please note that there is extra space at the end of First name and Phone number. I want to trim these spaces. Please suggest how to do that. Please also note that I have not defined the column names in my collection. I am directly copying it from excel so that if any changes done in excel then it reflect in the collection dynamically.
Thanks...
There are multiple action in collection manipulation object. You need to use read field action and rename field action with some logic.
You can for use action:
Object: Utility - Collection Manipulation
Action: Trim Collection
If you don't have it in your object, then you can add it to your object. Please see code below:
Dim i as integer
Dim j as integer
'For Each Column As DataColumn In Input_Collection.Columns
For j = 0 to Input_Collection.Columns.Count -1
For i = 0 to Input_Collection.Rows.Count -1
'dim x as string =CStr(Input_Collection.Rows(i)(j)).Trim()
Input_Collection.Rows(i)(j)= CStr(Input_Collection.Rows(i)(j)).Trim()
Next
Next
Output_Collection = Input_Collection
Or you may use
Object: Utility - Collection Manipulation
Action: Remove dot from headers
and in the code change "." to " "
Please find the exact code below and paste it in the code stage:
For Each Column As DataColumn In Input_Collection.Columns
Column.ColumnName=Microsoft.Visualbasic.Replace(Column.ColumnName," ","")
Next
Output_Collection = Input_Collection

Excel VBA process csv string into array

I have csv string (utf-8) obtained via a http download.
Depending on the situation the data in the string could contain a different number of columns, but each individual time a string is processed it will contain the same number of columns and be contiguous. (the data will be even).
The string could contain any number of rows.
The first row will always be the headings.
String fields will be encased in double quotes and could contain commas, quotes and newlines.
quotes and double quotes inside a string are escaped by doubling so "" and ''
In other words this is a well formed csv format. Excel through it's standard file open mechanism has no problem formatting this data.
However I want to avoid saving to a file and then opening the csv as I will need to process the output in some cases, or even merge with existing data on a worksheet.
(Added the following information via edit)
The Excel Application will be distributed to various destinations and I want to avoid if possible potential permissions issues, seems that writing nothing to disk is a good way to do that
I am thinking something like the following pseudo:
rows = split(csvString, vbCrLf) 'wont work due to newlines inside string fields?
FOREACH rows as row
fields = split(row, ',') 'wont work due to commas in string fields?
ENDFOR
Obviously that cant handle the fields containing special tokens.
What is a solid way of parsing this data?
Thanks
EDIT 13/10/2012 Data Samples
csv as it would appear in notepad (note not all line breaks will be \r\n some could be \n)
LanguageID,AssetID,String,TypeID,Gender
3,50820,"A string of natural language",3,0
3,50819,"Complex text, with comma, "", '' and new line
all being valid",3,0
3,50818,"Some more language",3,0
The same csv in Excel 2010 - opened from shell (double click - no extra options)
If you don't mind putting the data in your workbook: You could use a blank worksheet, add the data in 1 column, then call TextToColumns. Then if you want to get the data back as an array just load it from the UsedRange of the worksheet.
'Dim myArray 'Uncomment line if storing data to array.
'Assumes cvsString is already defined
'Used Temp as sheet for processing
With Sheets("Temp")
.Cells.Delete
.Cells(1, 1) = cvsString
.Cells(1, 1).TextToColumns Destination:=Cells(1, 1), DataType:=xlDelimited, _
TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=False, Tab:=False, _
Semicolon:=False, Comma:=True, Space:=False, Other:=False
'myArray = .UsedRange 'Uncomment line if storing data to array
End With
I can think of three possibilities:
Use Regular Expressions to process the text. There are plenty of examples available on SO and via google for separating strings like this.
Use the power of Excel: save the text to a temp file, open into a temp sheet and read the data off the sheet. Delete the file and sheet when done.
Use ADO to query the data. Save the string to a temp file and run a query on that to return the fields you want.
To offer any more specific advice I would need samples of input data and expected output

Excel VBA behaves different in different languages

Win-XP, Excel 2003
I have a range defined by a name, which is filled by a query. The same named range forms the source of a cell validation (in-cell dropdown list). In my VBA this range is accessed via a range object named LOVL2.
Each time the range is re-filled by the query, its name is redefined to include all rows I obtained through the query. This is done with statement
LOVL2.CurrentRegion.Name = LOVL2.Name.Name
the statement works fine as long as MS Office language is set to English, but the statement fails when MS office language is set to French .... I get Error 1004 "Invalid Name"
Anyone got an idea what is causing this only when MS Office language is set to FRENCH but not while in ENGLISH? (maybe problem with ";" vs "," within the object ??)
Thanks in advance MikeD
edit 12-Aug-2010
the REAL root cause is clear now:
the range's name is "L2PoP" which in the ENGLISH version is recognized as a valid name for a range - in that you can go to any empty sheet, select a range and name it "L2PoP".
Set your user language to FRENCH, go to any empty sheet, select a range and name it "L2PoP", and you get an error saying "Nom non valide".
so the real curing action is to give a different name to the range which is accepted by both French and English
I can only speculate about what is causing this, it may have to do with the fact that the first 2 characters look like a cell address, on the other hand "A1PoP " is a valid name, whereas "L2Foo" and "L1Foo" are invalid.
strange, but .....
which is filled by a query
By a query table?
A query table's result range already has a name which is the name (a bit sanitised) of the query table itself (set in the properties dialog). Which means you don't need to redefine anything.
And if you do, then try this code:
Sub asfgsdfg()
Dim n As Name
Set n = ThisWorkbook.Names("LOVL2")
'Or in case of a local name,
'Set n = ThisWorkbook.Worksheets("The worksheet").Names("LOVL2")
ChangeNamedRangeAddress n, n.RefersToRange.CurrentRegion
End Sub
Public Sub ChangeNamedRangeAddress(ByVal n As Name, ByVal NewRange As Range)
n.RefersTo = "='" & Replace(n.RefersToRange.Worksheet.Name, "'", "''") & "'!" & NewRange.Address(True, True, xlA1)
End Sub
EDIT
In regard to the follow-up... Most strange and amusing.
Try using a leading underscore or something?

Resources