Using hash sign (#) in the Excel sheet name - excel

I'm trying to solve an issue I have when I'm trying to use OLE DB for reading Excel files.
I found that the problem is because there is a hash mark (#) in the sheet name.
Unfortunately, I can't rename the sheet.
So after some tries, I've succeeded to read a full sheet by adding quotation marks ('):
Before
Select * from [" + sheetName + "$];
After (working)
Select * from ['" + sheetName + "$'];
But then I got stuck when trying to read a range from the sheet with the OLE DB feature:
Select * from [" + sheetName + "$" + fromCell + ":" + toCell + "];
When I try to send this command, it's seems like the # is replaced by . and then it cannot find the sheet.
I've tried many combination and escape codes and didn't find any solution. How can I access this file?

Your final output should look like this
'MySheet$A1:B2'
So your select should be
var SheetName = "MySheet";
var fromCell = "A1";
var toCell = "B2";
var sql = "Select * from ['" + SheetName + "$" + fromCell + ":" + toCell + "']";
Console.WriteLine(sql);
// Output
// Select * from ['MySheet$A1:B2']
Also consider parametrising your sql for better readability and also preventing sql code injection. You can find a guide for how to do it at OleDbCommand.Parameters.

Related

errors importing CSV (delimited) into DAO database using vba and SQL from

I am stymied by an SQL mediated import of a CSV file using VBA code. I am using a Third EXCEL macro/spreadsheet, to analyze a LEFT JOIN of 2 files, one as an XLXS and the other as a CSV.
I suspect that part of the problem may be how the SQL command is used, for a FROM reference to an excel file. I am using Excel VBA, 2010, The 14 Database Access Engine.
I want to end with an SQL statement that pulls from an external comma delimited CSV file
I anticipate heading the macro with this pseudo code, in a stand-alone macro enabled excel file:
dbEngine = CreateObject(DAO.engine ... )
set DB = dbEngine.OpenDatabase(theNormalExternalExcellFile,....)
For the SQL statement, in pseudo-code, I want this:
SELECT fields
FROM [Table$] ' a normal external excel file
LEFT JOIN [an external CSV, comma delimited file]
ON...
GROUP...
I can successfully import an XLXS, or the CSV, independently, in a simple SQL statement, yet when I place the outside file references within an SQL's FROM clause, I get one of two errors, depending on how I play with the code: an Invalid File Path, or an error in the FROM Clause. The path is -not- invalid.
The error is shown, below, where it occurs, at the recordset instruction.
I also provide alternative SQL strings, which I had played with to test where in the code the error is generated.
'the Seating Chart
strPathSource = ThisWorkbook.Worksheets("Logic").Range("rngPathSource")
'strFileNameSource = ThisWorkbook.Worksheets("Logic").Range("rngFileNameSource")
'strFileNameSourceWOExt = Left(strFileNameSource, Len(strFileNameSource) - 4)
'the attendance
strPathAttendance = ThisWorkbook.Worksheets("Logic").Range("rngPathAttendance")
strFileNameAttendance = ThisWorkbook.Worksheets("Logic").Range("rngFileNameAttendance")
strFolderAttendance = ThisWorkbook.Worksheets("Logic").Range("rngFolderAttendance")
strFileNameAttendanceWOExt = Left(strFileNameAttendance, Len(strFileNameAttendance) - 4)
Set dbE = CreateObject("Dao.DBEngine.120")
Set db = dbe.OpenDatabase(strPathSource, True, False, "Excel 12.0;HDR=Yes")
''Set db = DAO.OpenDatabase(strFolderAttendance, True, False, "text;HDR=Yes;FMT=Delimited(,)")
'[Master$] is a tab on the spreadsheet at strPathSource
'[Attendance#csv]
' This reference to the table at strPathAttendance which otherwise works: [Attendance#csv]
' when not inside the FROM clause
strSQL = _
"SELECT tM.Job, Count(tA.Name) AS CountOfName" _
& " FROM [Master$] tM" _
& " LEFT JOIN" _
& " (SELECT * FROM [text;HDR=Yes;FMT=Delimited(,);Database='" _
& strPathAttendance & "'].[" & strFileNameAttendanceWOExt & "#csv]) tA" _
& " ON (tM.GivenName = tA.GivenName) AND (tM.SurName = tA.SurName)" _
& " GROUP BY tM.Job" _
& " ORDER BY tM.Job, Count(tA.Name)"
'Debug.Print strSQL
' This is the reported value for the string, strSQL, particularly the FROM clause:
' SELECT tM.Job, Count(tA.Name) AS CountOfName FROM [Master$] tM LEFT JOIN
' (SELECT * FROM
' [text;HDR=Yes;FMT=Delimited(,);Database=T:\Solutions Team Shared Folder\Seats -
' Attendance\Attendance.csv].[Attendance#csv]) tA
' ON (tM.GivenName = tA.GivenName) AND (tM.SurName = tA.SurName)
' GROUP BY tM.Job ORDER BY tM.Job, Count(tA.Name)
'' putting a single or double quote, around the database path, does not change the error
Set rstR = db.OpenRecordset(strSQL)
'Error:
' 'T:\...\...\Attendance.csv' is not a valid path. Make sure that
' the path name is spelled correctly and that you are connected to the server
' on which the file resides.
' ALT SQL strings, to test what's going on.
'strSQL = _
' "Select * FROM [Attendance#csv]"
'strSQL = _
' "Select * FROM (Select * FROM [Excel 12.0;HDR=Yes;Database=" & strPathSource & "].[Master$])"
'strSQL = _
' "SELECT * FROM [text;HDR=Yes;FMT=Delimited(,);Database=" _
' & strPathAttendance & "].[" & strFileNameAttendanceWOExt & "#csv]"
'strSQL = _
' "Select * FROM [Excel 12.0;HDR=Yes;Database=" & strPathSource & "].[Master$]"
When connected to text files with Jet/ACE SQL, the database parameter needs to reference the directory path not any specific text file. The period qualifier will then specify the individual file.
Therefore, simply remove the file name and extension from strPathAttendance (without quotes). So query should look like the below:
SELECT tM.Job, Count(tA.Name) AS CountOfName
FROM [Master$] tM
LEFT JOIN
(SELECT * FROM
[text;HDR=Yes;FMT=Delimited(,);Database=T:\Solutions Team Shared Folder\Seats -
Attendance].[Attendance#csv]) tA
ON (tM.GivenName = tA.GivenName) AND (tM.SurName = tA.SurName)
GROUP BY tM.Job
ORDER BY tM.Job, Count(tA.Name)

sudden change in string value during a browse value change

During a Value-Change inside a browse, my string value suddenly changes, specifically the string(9) will change to string(0).
sample:
in my combo-box, i used a list-item-pair with following code:
cb-name:LIST-ITEM-PAIRS = ?.
cb-name:DELIMITER = '?'.
FOR EACH employee WHERE employee.date-resigned = ? NO-LOCK BY employee.employee-no.
cb-name:ADD-LAST(TRIM(STRING(employee.employee-no, '99999999') + " - " + employee.last-name + ", " + employee.first-name + " " + SUBSTRING(employee.middle-name,1,1)) + ".",employee.employee-no).
END.
cb-name:SCREEN-VALUE = cb-name:ENTRY(1).
in the value-changed of browse:
ASSIGN cb-name:SCREEN-VALUE =
STRING(TRIM(STRING(employee.employee-no, '99999999') + " - " + employee.last-name + ", " + employee.first-name + " " + SUBSTRING(employee.middle-name,1,1)) + "." ,
STRING(employee.employee-no, '99999999')).
if the employee no has a string value of 9, progress will change it to 0.. producing an error message that has an invalid value..
ex: from 819001 /*correct*/ to 810001 /*incorrect*/
if there is no string(9), it will display like:818002
if i message the STRING(employee.employee-no, '99999999')), it will display the correct string value
Version doesn't matter in this case, apparently. I just simulated it in 10.2B08 using a temp-table with the named tables. The problem is when you're assigning the screen-value to the combo you're trying to convert the whole string (employee-no + names + separators) into format 99999999.
Since your combo is list-item-pairs
('Whatever I want it to display','the real value',
'and so on display' , 'and so forth value')
your solution is to assign the screen value just to the real value, disregard the label. In other words, as simple as changing your value-changed code to
ASSIGN cb-name:SCREEN-VALUE = STRING(employee.employee-no, '99999999') .
It worked for me. Let me know if you are still having trouble with it.

Passing array from Java to VBScript

I have two questions:
1. If we can pass an array to VBSCript using java. I am able to pass single variables to VBSCript using following command
Runtime.getRuntime().exec("wscript openChartsDevice.vbs " + fileName + " " + range);
But when I pass a String array, it says type mismatch. I am catching the array passed in
Dim arr()
any Suggestions?
Edit 1 Following question has been answered
2. I am using following Vbscript to create chart in excel
Dim oExl,excelPath,objWriteSheet,objWriteWorkbook
Dim oMychartProcs
Set oExl=CreateObject("Excel.Application")
Set objWriteWorkbook = oExl.Workbooks.Open("SomeExcelfile.xlsx")
Set objWriteSheet = objWriteWorkbook.Worksheets(1)
Set oMychartProcs = objWriteWorkbook.Charts.Add
oMychartProcs.SetSourceData objWriteSheet.Range(Cells(2,1),Cells(7,6))
oMychartProcs.ChartType = 4
oMychartProcs.Name = "ChartName"
oMychartProcs.Activate
I have given the range as A2:F7. when I enter
oMychartProcs.SetSourceData objWriteSheet.Range("A2:F7")
the chart is created perfectly but when I use the
Range(Cells(2,1),Cells(7,6))
whole excel sheet is converted to chart.
I want to provide the range through parameters so I want above formula to work. I've searched a lot and could not find a definitive way for it. Thank you.
You can not pass array as an object. But you can pass its elements as string parameters to the vbscript function with a space as the delimiter.
openChartsDevice.vbs " + fileName + " " + arg[0] + " " + arg[1] + " " + arg[2].....
You can a create a method in java to pass an array and return a string
arg[0] + " " + arg[1] + " " + arg[2].....
Another Approach: Create a file with input parameters. Update your VBScript to refer to that input file to get the parameters instead of looking for command line arguments.
I don't know JScript. But the way to get in VBScript the same thing.
For Each thing in Array()
A = A & thing & " "
Next
You are actually asking how to turn an array into a delimited string not a vbscript array.
See this article which your question title implies you are interested in.
http://blogs.msdn.com/b/ericlippert/archive/2003/09/22/53061.aspx

Escape strings when creating a dynamic update statement

I have a stored procedure that is generating a string that it will call EXECUTE() on. The string contains an UPDATE statement. However, the columns and values that it is executing are not known beforehand. These are coming into the stored procedure through an XML string. I then use XML queries to get the data out and into a temporary table.
This is not sanitizing the data.
DECLARE #TBL_FLD TABLE (
TBL VARCHAR(MAX),
COL VARCHAR(MAX),
VAL VARCHAR(MAX)
);
-- Fill #TBL_FLD via xml parsing (omitted for brevity)
DECLARE TBL_CURSOR CURSOR FOR
SELECT distinct (TBL) FROM #TBL_FLD;
OPEN TBL_CURSOR;
WHILE 1 = 1
BEGIN
FETCH NEXT FROM TBL_CURSOR INTO #TABLE_NAME
IF ( ##FETCH_STATUS <> 0 )
BREAK
SET #SETTING_STR = '';
SELECT #SETTING_STR = STUFF( ( SELECT ', ' + COL + ' = ''' + VAL + '''' FROM #TBL_FLD WHERE TBL = #TABLE_NAME FOR XML PATH('') ), 1, 2, '');
SET #SQL_QUERY += 'UPDATE ' + #TABLE_NAME + ' SET ' + #SETTING_STR + ' WHERE KEY = ' + CONVERT(VARCHAR(MAX), #KEY_VAL) + '; ';
END
CLOSE TBL_CURSOR
DEALLOCATE TBL_CURSOR
EXECUTE (#SQL_QUERY);
I trust the COL field of #TBL_FLD, but the VAL will have come from a user. Which leaves a massive security hole since I am just concatenating the data together. There has to be a better way.
Since there are an unknown number of columns, I can't easily create parameters for the statement so that the data is cleaned up. If worst comes to worst, I can do it, (see the answer to Dynamically Create Update SQL In Stored Procedure) but it will be uglier than I would like.
Is there a function, or method, to sanitize the data, before I blindly add it to the statement? Or is there a better way to do what I'm trying to do?
I think that just doubling single quotes with a REPLACE on VAL would fix any issues since an attacker would not be able to exit the "string scope" to execute arbitrary code :
SELECT #SETTING_STR = STUFF( ( SELECT ', ' + COL + ' = ''' + REPLACE(VAL, '''', '''''') + '''' FROM #TBL_FLD WHERE TBL = #TABLE_NAME FOR XML PATH('') ), 1, 2, '');
I don't remember a built-in T-SQL function that does the same thing

read excel to datatable with intermixed data

I want to read excel to datatable.But I have a problem.I have a column "ALS" which contains mixed type data.When I read excel to dataset "Kukla" is DbNul value instead.I cant read such columns all datas
example, column data:
2000
Kukla
2000
1000
1000
String sConnectionString =
"Provider=Microsoft.Jet.OLEDB.4.0;" +
"Data Source=" + "C:\\DrcrUpload\\" + filePath + ";" +
"Extended Properties=\"Excel 8.0;HDR=Yes;IMEX=1\"";
OleDbConnection objConn;
objConn = new OleDbConnection(sConnectionString);
OleDbCommand objCmdSelect = new OleDbCommand("SELECT * FROM" + "[" + name + "]", objConn);
objAdapter1.Fill(objDataset1);
You have a few options
1.Change the registry setting TypeGuessRows = 0
2.List all possible type variations in the first 8 rows as 'dummy data' (eg memo fields/nchar(max)/ errors #N/A etc)
This thread may help also Link

Resources