Excel: Saving query results directly to CSV file - sql

I have a dataset in Excel, of which I have to save an assorted part to a new csv file. I have used SQL to select the part required to be saved. I was hoping somebody would guide me about saving this selection to csv using SQL.
SQL gives me a recordset but I would like to loop through it only as a last resort. I am hoping there is a better approach that directly saves the entire result from within the query itself if possible.
Something like the solution by Remou on Want VBA in excel to read very large CSV and create output file of a small subset of the CSV is what I'm looking for. But unfortunately I can't get that to work.

Assuming you are in Excel VBA, has an ADODB opened with a Recordset object connected to a database and you want to save the content into a CSV (from within the Excel VBA).
The easiest is actually still by looping through the records in the recordset.
However, since you already rule that out (for whatever reasons), the next option would be to use the Recordset.Save <StreamObject> method. Create a System.IO.Streamwriter object to pass to the Recordset.Save.
OR, another way if you are using Jet SQL is:
conDB.Execute "SELECT * INTO [Text;Database=" _
& vsCSVFolder _
& ";HDR=No;FMT=Delimited].[" _
& vsCSVFileame _
& "] FROM Attendance", _
DBExport, _
adCmdText Or adExecuteNoRecords
Hope this helps.

Related

Importing a text file into Postgres using ODBC

I am trying to directly import a text file into Postgres, but using ODBC. I realize that this is a bit of an odd thing to do, but ODBC does a good job of fixing/ignoring errors in the text files and Postgres' Copy command is very, very picky. I use Copy when I can and ODBC where I can't.
I am currently doing this in two steps. ODBC Import to Access and then from Access to Postgres but I recently learned over on MSDN I may be able to do this in one step but am having trouble with the SQL.
Here is the code I am using:
Dim TextConnection As New System.Data.OleDb.OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=c:\PathToTextFile;Extended Properties=""Text;HDR=No""")
Dim TextCommand As System.Data.OleDb.OleDbCommand
TextCommand = New System.Data.OleDb.OleDbCommand("SELECT * INTO [ODBC;Driver={PostgreSQL};" & _
" Server=server;Database=database;Uid=UserName;Pwd=Password;].[TableName] FROM [textfile.txt]", TextConnection)
TextCommand.ExecuteNonQuery()
I am getting this error: Query input must contain at least one table or query.
I am not where to go from here in debugging this. It also just might now be possible and that would be good to know.

MS Access Issue

Hello Stackoverflow community!
I have run into an issue and I'd love some advice.
I'm working with MS Access and I am trying to append two particular fields from one table to another; however this implementation is in a form and it gets a little complicated... So, I'll explain everything the best that I can
BACKGROUND INFORMATION:
First and fore most, I have two tables; one of which is a linked excel spread sheet from another directory (who is not willing to change any formatting what so ever, so I CANNOT make ANY changes to this file and it is being updated on a daily basis). This excel spreadsheet is very large and contains somewhere around 50 columns
The other table is not anywhere near as large but has around 20 columns and is meant to extract two columns from the excel spreadsheet (the first column and the third column). I'm trying to make a form for this database to be as user-friendly as possible and not many people in my office are familiar with the technicalities of Access queries and programming in VBA.
THE SITUATION:
On my form, the user will enter data into TextBoxA, from there they will click a button; this button will trigger a search through the linked excel spreadsheet for the data that was typed into TextBoxA. It will then copy the data from Field1 (which was the typed data) and Field3 and append these selected fields into the first two fields of the table in my Access Database. All of this is being done through a segment of VBA code
Private Sub CmdCloseForm_Click()
If IsNull(Me.TextBoxA) Or Me.TextBoxA = "" Then
MsgBox ("Field is empty, please try again!")
Else
Dim VendorNum As String
SearchingValue = Me.TextBoxA
Dim SQL As String
SQL = "INSERT INTO tbleRecord (Field1,Field2)" & _
"SELECT * " & _
"FROM tbleLinkedExcel " & _
"WHERE Field1 = '" & SearchingValue & "';"
DoCmd.RunSQL SQL
End If
End Sub
So the biggest issue here is that in Field1, and every time I try to run the code,
I receive an error; which I am assuming it is because of the space (unfortunately I cannot give the ACTUAL variable names out as it is confidential)
ERROR MESSAGE
The INSERT INTO statement contains the following unknown field name: 'FIELD 1'. Make sure you have typed the name correctly, and try the operation again.
The thing is, is that this 'FIELD 1' variable/name is not in my code, but in the linked excel spreadsheet (again, I am not able to change ANYTHING on this spreadsheet).
Thanks guys!

Filter a query based on a Text Box value in VBA Excel

I have a form in Excel with two TextBoxes. I’m trying to get the value from those TextBoxes as query criteria in VBA Excel.
I have tried different ways to achieve this, but it just doesn't work.
Thanks! Here is the code.
strSQL = "SELECT * " & _
"FROM reporte_fallas.reportefallas reportefallas_0 " & _
"WHERE (reportefallas_0.CREADT BETWEEN [Forms]![QueryUserForm]![StartDateTextBox] AND [Forms]![QueryUserForm]![EndDateTextBox])"
Please see the following answer:
How to add parameters to an external data query in Excel which can't be displayed graphically?
Another idea could be to use a DAO or ADO recordset, if you're connecting to external data.

How can I manually define column types in OLEDB/JET DataTable?

I am importing data from an Excel spreadsheet to a VB.NET DataTable. This Excel spreadsheet has a lot of garbage data in the first 18 rows, including a lot of empty cells. I ultimately remove these rows in post-processing, but I need to access the Excel file as is, without modifying it by hand at all.
I realize that setting IMEX=1 instructs the Jet engine to assume all columns are text. However, I have an issue with setting it to another value (explained more below). So, the default Jet engine column type scan wouldn't work particularly well.
I'd like to either:
Manually define column types before the import
Force Excel to scan many more rows (I believe the default is 8) to determine the column type
However, I do have an issue with idea #2. I do not have administrative rights to open regedit.exe, so I can't modify the registry using that method. I did circumvent this before by importing a key somehow, but I can't remember how I did it. So #1 would be an ideal solution, unless someone can help me carry out idea #2.
Is this possible? Currently, I'm using the following method:
If _
SetDBConnect( _
"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & filepath & _
";Extended Properties=""Excel 8.0;HDR=Yes;IMEX=1""", True) Then
dtSchema = _dh.GetOleDbSchemaTable()
If _dh.Errors <> "" Then
Throw New Exception("::LoadFileToBuffer.GetOleDbSchemaTable::" & _dh.Errors())
End If
For Each sheetRow In dtSchema.Rows
If sheetRow("TABLE_NAME").ToString() = "TOTAL_DOLLARS$" Then
totalDollars = sheetRow("TABLE_NAME").ToString()
ElseIf sheetRow("TABLE_NAME").ToString() = "TOTAL_UNITS$" Then
totalUnits = sheetRow("TABLE_NAME").ToString()
End If
Next
'Get total dollars table
sql.Append("SELECT * FROM [" & totalDollars & "]")
dtDollars = _dh.GetTable(sql.ToString())
End If
Thank you!
You should be able to say:
sql.Append("SELECT * FROM [" & totalDollars & "$A18:X95]")
Where totalDollars is a sheet name and x95 is the last valid row. You will not be able to include headers unless they are available at row 18.

ADO recordset fails on "memo" datatype during import into Excel

I am trying retrieve data from a SQL server, for use in some Excel 2003 macros. I would like to avoid the use of QueryTables, as I don't want this intermediate step of writing and reading from actual sheets. It seems time-consuming and pointless.
I have managed to get the recordset, but it contains empty data where the datatype is "memo", on the server.
Further, the program crashes where it tries to store the data into a Range. It appears to make it to the first "empty" field and then it gives me a 1004 Error Code.
Clearly the memo field is giving me grief. Can anyone make a suggestion as to how to get around this, or what I should be doing differently?
objMyConn.connectionString = "ODBC;" _
& "Provider=SQLOLEDB;DRIVER={SQL Server};SERVER=VANDB;" _
& "APP=Microsoft Office 2003;DATABASE=WPDB_BE;Trusted_Connection=Yes;"
objMyConn.Open
I've been searching online for ages, but this Access / ADO / Excel stuff is exceedingly painful. Please help.
Edit 1: I later modified the SQL query with "TOP 1" (SQL version of "LIMIT 1") and found that with that recordset, the memo fields were returned correctly. Similarly, I could SELECT a single problematic field, and get more rows, e.g. "SELECT TOP 52 bad_field FROM ..."
So I suspect that the issue is an ADO connection data size limit of some sort? It seems the Access "memo" type is simply like a "MEDIUMTEXT" MySQL type, so how would I get around such a limit? It's a separate question then, but what alternatives are there to the ADO connections?
You can use your ADO Connection object (objMyConn) to discover the data type (among other attributes) as ADO interprets it:
With objMyConn.OpenSchema(adSchemaColumns, Array(Empty, Empty, "your_table_name_here"))
.Filter = "COLUMN_NAME = 'your_column_name_here'"
MsgBox .Fields("DATA_TYPE").Value
End With
This will return the integer value of its respective SchemaEnum enum value, use the object browser to discover the enum value. Posting the results here could give a further clue to your problem.