How to modify an Excel spreadsheet, without Excel, using VBScript? - excel

I need to add a row to a spreadsheet using VBScript on a PC that does not have Microsoft Office installed.
I tried [Set objExcel = CreateObject("Excel.Application")]
Since Excel does not exist on the PC I cannot create this object.
Is there a way to modify a spreadsheet without Excel?

To use the code below, create an Excel workbook named "Test.xls" in the same folder as the vbscript file.
In Test.xls, enter the following data in cells A1 thru B4:
First Last
Joe Smith
Mary Jones
Sam Nelson
Paste the vbscript code below into a .vbs file:
Const adOpenStatic = 3
Const adLockOptimistic = 3
filename = "Test.xls"
Set cn = CreateObject("ADODB.Connection")
cn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & filename & _
";Extended Properties=Excel 8.0"
query = "Select * from [Sheet1$A1:B65535]"
Set rs = CreateObject("ADODB.Recordset")
rs.Open query, cn, adOpenStatic, adLockOptimistic
rs.AddNew
rs("First") = "George"
rs("Last") = "Washington"
rs.Update
rs.MoveFirst
Do Until rs.EOF
WScript.Echo rs.Fields("First") & " " & rs.Fields("Last")
rs.MoveNext
Loop
At a command prompt, type:
CSCRIPT Yourfile.vbs
It will add a name to the spreadsheet and then write out all the names.
Joe Smith
Mary Jones
Sam Nelson
George Washington

You can try to use the Microsoft Jet Driver:
See here for a vbscript sample. See here for more links and ways to insert rows.

Not without extreme difficulty. Microsoft have released their file format specifications, Excel here, but these are not to be taken lightly, and I think you will have a difficult time using VBScript.

I know...years later but today I needed to figure out how to access an Excel spreadsheet using vbScript without loading Excel on my server. I searched around the net and found your information helpful, but I still needed more so I kept searching. I finally found the solution that I needed and wanted to share it here just in case anyone else has the same issues that as I did.
I was trying to access (read/write) an Excel spreadsheet using vbScript on a Windows 2008 server and I didn't want to install Excel on my server. My solution was here (it uses PowerShell but it is easy to decypher to VBS):
Using vbScript to read from an Excel spreadsheet without Excel installed
Using vbScript to write to an Excel spreadsheet without Excel installed
I hope that this helps someone that needs the same solution in the future.
L8r...
UCG

This is the final version of the script I used, thank you all for the help.
Dim arrValue
arrValue = Array("Test","20","","I","2.25","3.9761","20","60","12","1","","1","1","1")
AddXLSRow "C:\Test.xls", "A1:N109", arrValue
Sub AddXLSRow(strSource, strRange, arrValues)
'This routine uses the data from an array to fill fields in the specified spreadsheet.
'Input strSource (String) = The Full path and filename of the spreadsheet to be used.
'Input arrValues (Array) = An array of values to be added to the spreadsheet.
Dim strConnection, conn, rs, strSQL, index
strConnection = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & strSource & ";Extended Properties=""Excel 8.0;HDR=Yes;"";"
Set conn = CreateObject("ADODB.Connection")
conn.Open strConnection
Set rs = CreateObject("ADODB.recordset")
strSQL = "SELECT * FROM " & strRange
rs.open strSQL, conn, 3,3
rs.AddNew
index = 0
For Each field In rs.Fields
If field.Type = 202 Then
field.value = arrValues(index)
ElseIffield.Type = 5 And arrValues(index) <> "" Then
field.value = CDbl(arrValues(index))
End If
If NOT index >= UBound(arrValues) Then
index = index + 1
End If
Next
rs.Update
rs.Close
Set rs = Nothing
conn.Close
Set conn = Nothing
End Sub

Without Excel installed I cannot see how you will be able to change an Excel document.
However, If your are using Excel 2007 spreadsheets (xslx) then you should able to use the OpenXML functionality of the .NET Framework to update the contents without Excel physically being installed.
Take a look here for more information on Office OpenXML.

You might want to see this question. It's C# based, but should give you an insight into the techniques for accessing spreatsheets.

Sorry to be late to the party. The fact that no one's mentioned VSTO probably means that I'm misunderstanding the question. And at any rate I've heard mixed reviews from folks using it.

I believe the simple answer to your question is no because you need the Excel COM object which is only installed when Excel is installed. This used to be one of the real drawbacks of writing an Office app--the need for the entire application (Excel, Word or whatever) in order for an end-user to use it.

Use EPPlus.
epplus.codeplex.com
You can do most things that you can do with VSTO, without excel installed.

Related

Get file path from explorer search in excel

I am very new to using macros so am looking for solutions online.
What I want to do is exactly the same as has been asked in another question (Extract file names from a File Explorer search into Excel) however I cannot get the proposed solution to work (honestly, I am too unexperienced to understand it).
I want to be able to search for files in a given location for a keyword within the content of the files, not the filename, and be able to get a list of file paths into excel for the files that are found through the search.
I was able to find a code that does the first part, i.e. opening windows explorer in a specific folder and finding the file(s) for a specific keyword.
Sub Search_files ()
dim eSearch As String
eSearch = "explorer " & Chr$(34) & "search-ms://query=System.Generic.String:" & [search term here] & "&crumb=location:" & [Directory Here] & Chr$(34)
Call Shell (eSearch)
End Sub
Next I would need to get the path of the files that turned up in the search into excel.
The solution proposed in the previous question says "Assuming the location is indexed you can access the catalog directly with ADO (add a reference to Microsoft ActiveX Data Objects 2.x)" and proposed the following:
Dim cn As New ADODB.Connection
Dim rs As New ADODB.Recordset
Dim sql As String
cn.Open "Provider=Search.CollatorDSO;Extended Properties='Application=Windows'"
sql = "SELECT System.ItemNameDisplay, System.ItemPathDisplay FROM SystemIndex WHERE SCOPE='file:C:\look\here' AND System.Kind <> 'folder' AND CONTAINS(System.FileName, '""*.PDF""') AND CONTAINS ('""find this text""')"
rs.Open sql, cn, adOpenForwardOnly, adLockReadOnly
If Not rs.EOF Then
Do While Not rs.EOF
Debug.Print "File: "; rs.Collect(0)
Debug.Print "Path: "; rs.Collect(1)
rs.MoveNext
Loop
End If
I added a reference to Microsoft ActiveX Data Objects 2.x and replaced 'file:C:\look\here' with 'file:{myPath}' and ('""find this text""')" with ('""{myText}""')" . I do not get errors, it just doesn't do anything. I specify the files I have in the test folder are pdfs (since this code only looks for pdf files).
The author commented "I had to add: set cn = NEW ADODB.Connection set rs = NEW ADODB.Recordset before using any of the commands and then it worked perfectly." I did that as well but I can't get it to work.
Thanks to anyone who can suggest a solution/explain how the above works!

Retrieving data from Excel spreadsheet to Excel spreadsheet in a block

Here's my problem :
I want to retrieve data from an Excel XML spreadsheet (*.xlsx) within another Excel spreadsheet without opening it. So I gave a chance to OLEDB with the ACE Provider.
The connection worked and I made what I wanted, by looping through my recordset. But now I want some optimization, i.e. putting my recordset into excel in a block instead of looping through it.
Therefore I made something like this :
Sub RetrieveData()
Dim con As ADODB.Connection
Dim rs As ADODB.Recordset
Set con = New ADODB.Connection
Set rs = New ADODB.Recordset
With con
.Provider = "Microsoft.ACE.OLEDB.12.0"
.ConnectionString = "Data Source=Path\File.xlsx; _
Extended Properties=""Excel 12.0 Xml;HDR=NO;IMEX=1"""
.Open
Set rs = .Execute("Select * From [Sheet1$]")
'Problem here
Range(Cells(1, 1), Cells(rs.RecordCount, rs.Fields.Count - 1)) = rs
.Close
End With
Exit Sub
The thing here, is that I'm currently dealing with technologies which I don't know much about them and can't find any documentation on them (e.g. Microsoft ACE 12.0 Provider for OLEDB).
Regards.
(And don't even hesitate to correct my poor grammar)
I think this is what you need:
Cells(1,1).CopyFromRecordset rs
Quite simple, don't you think. But put it instead of this line:
Range(Cells(1,1)................ = rs
And remember to remove comment: 'Problem here :)
By the way, data you get in your sheet don't include columns heading. But I hope you'll cope with that separately.

Is it possible to embedded a Sqlite database into an excel 2007 file (zip archive)

I'm working on an excel application that requires a database back end. My preference is to use SQLite 3 and to make this as seamless and portable as possible for the end user.
Recently I have learned that an Excel 2007 file is simply a zip archive with a xlsm extension. My question is this, can I store my back-end SQLite 3 database in the Zip archive and use ODBC to interact with the database. If so, can anyone point me to some background information, articles, guidance on achieving this objective. Are there any downsides to this approach or a better alternative I should know about.
Thanks for your input.
Some notes. So far, no one has complained that the file does not open. Note that the Excel file is saved before the ADO code is run.
Very hidden:
ThisWorkbook.Worksheets("Courses").Visible = xlVeryHidden
ThisWorkbook.Worksheets("System").Visible = xlVeryHidden
A snippet of code:
Const gCN = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source="
<...>
Set rs = CreateObject("ADODB.Recordset")
Set cn = CreateObject("ADODB.Connection")
Set fs = CreateObject("Scripting.FileSystemObject")
scn = gCN & ThisWorkbook.FullName _
& ";Extended Properties=""Excel 8.0;HDR=Yes;"";"
cn.Open scn
''If they do not have an ID, they do not exist.
sSQL = "SELECT ID,FirstName,LastName, " _
& "CourseName,AdditionalText,Format(ExpiryDate,'dd/mm/yyyy') As ExpiryDate " _
& "FROM [Applicants$] WHERE DateCancelled Is Null AND ID Is Not Null " _
& "AND (FirstName Is Null OR LastName Is Null Or CourseName Is Null " _
& "Or ExpiryDate Is Null) " & sWhere
rs.Open sSQL, cn
References:
Excel ADO
Connection strings
Most of the methods available to Jet can be used with Excel
Fundamental Microsoft Jet SQL for Access 2000
Intermediate Microsoft Jet SQL for Access 2000
Advanced Microsoft Jet SQL for Access 2000
Edit re Comments
I did not find the leak particularly bad, but I did not run many iterations, and this is quite a good machine.
The code below uses DAO, which does not cause a memory leak.
'Reference: Microsoft Office 12.0 Access Database Engine Object Library
Dim ws As DAO.Workspace
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim sDb As String
Dim sSQL As String
sDb = ActiveWorkbook.FullName
Set ws = DBEngine.Workspaces(0)
Set db = ws.OpenDatabase(sDb, False, True, "Excel 8.0;HDR=Yes;")
sSQL = "SELECT * FROM [Sheet1$];"
Set rs = db.OpenRecordset(sSQL)
Do While Not rs.EOF
For i = 0 To rs.Fields.Count - 1
Debug.Print rs.Fields(i)
Next
rs.MoveNext
Loop
rs.Close
db.Close
ws.Close
'Release objects from memory.
Set rs = Nothing
Set db = Nothing
Set ws = Nothing
Acknowledgement: http://www.ozgrid.com/forum/showthread.php?t=37398
Here is an alternative.
1) At Open (EVENTs in VBA) unzip from Excel .xlsm, sqlite and dbFile.
2) Process what you .....
3) At save (EVENTs in VBA) the book an then attach the Excel .xlsm ,sqlite , dbFile in Excel .xlsm.
Excel rewrites the file every time it is saved, so your own added file would be deleted.
Furthermore, there is no SQLite driver that can access database files inside of zip archives.
You would have either to ship the database file alongside with the Excel file, or to recreate the database with a list of SQL commands when your application detects that the DB file is missing.
This still requires that some SQLite (ODBC) driver is installed on the user's machine.
The most seamless and portable way to store data in an Excel file is to store it in an Excel sheet, as mentioned by Remou. However, it's possible that the ADO driver will refuse to open the file when it's already open in Excel, so that you have to use Excel functions to access the data.
Try using http://code.google.com/p/pyinex/
this embed the Python interpreter in Excel

Access - Excel Integration

Hey all, have been working on designing a new database for work. They have been using Excel for their daily reports and all the data is stored in there, so I decided to have the back-end of the database in Access and the front-end in Excel, so any analytical work can be easily performed once all the data has been imported into Excel.
Now I'm fairly new to VBA, slowly getting used to using it, have written some code to transfer one of the calculated tables from Access to Excel:
Option Explicit
Public Const DataLocation As String = "C:\Documents and Settings\Alice\Desktop\Database\TestDatabase21.accdb"
Sub Market_Update()
Call ImportFromAccessTable(DataLocation, "Final_Table", Worksheets(2).Range("A5"))
End Sub
Sub ImportFromAccessTable(DBFullName As String, TableName As String, TargetRange As Range)
Dim cn As ADODB.Connection, rs As ADODB.Recordset, intColIndex As Integer
Set TargetRange = TargetRange.Cells(1, 1)
' open the database
Set cn = New ADODB.Connection
cn.Open "Provider=Microsoft.ACE.OLEDB.12.0; Data Source=" & DBFullName & ";"
Set rs = New ADODB.Recordset
With rs
' open the recordset
' .Open TableName, cn, adOpenStatic, adLockOptimistic, adCmdTable
' all records
.Open "SELECT * FROM Final_Table", cn, , , adCmdText
' filter records
For intColIndex = 0 To rs.Fields.count - 1 ' the field names
TargetRange.Offset(0, intColIndex).Value = rs.Fields(intColIndex).Name
Next
TargetRange.Offset(1, 0).CopyFromRecordset rs ' the recordset data
End With
rs.Close
Set rs = Nothing
cn.Close
Set cn = Nothing
End Sub
Sub Company_Information()
Dim companyName As String
On Error GoTo gotoError
companyName = Application.InputBox(Prompt:="Enter Company Name", _
Title:="Company Name", Type:=2)
Exit Sub 'Don't execute errorhandler at end of routine
gotoError:
MsgBox "An error has occurred"
End Sub
The above code works fine and pulls up the desired calculated table and places it in the right cells in Excel.
I've got two problems that I'm having trouble with; firstly I have some cell-formatting already done for the cells where the data is going to be pasted into in Excel; I want it to apply the formatting to the values as soon as they are pasted in Excel.
Secondly; I have an add-on for Excel which updates some daily Stock Market values; these values need to be transferred into Access at the end of each working day, to keep the database maintained, I tried some code but have been having some problems with it running.
The code for this part can be seen following:
Sub UPDATE()
Dim cnt As ADODB.Connection
Dim stSQL As String, stCon As String, DataLocation As String
Dim stSQL2 As String
'database path - currently same as this workbook
DataLocation = ThisWorkbook.Path & DataLocation
stCon = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & DataLocation & ";"
'SQL code for GL Insert to Access
stSQL = "INSERT INTO Historical_Stock_Data SELECT * FROM [Portfolio] IN '" _
& ThisWorkbook.FullName & "' 'Excel 8.0;'"
'set connection variable
Set cnt = New ADODB.Connection
'open connection to Access db and run the SQL
With cnt
.Open stCon
.CursorLocation = adUseServer
.Execute (stSQL)
End With
'close connection
cnt.Close
'release object from memory
Set cnt = Nothing
End Sub
I get the following error with this.
Run-time Error '-2147467259 (80004005)'
The Microsoft Jet database engine cannot open the file 'Cocuments and Settings\Alice\Desktop\Database'. It is already opened exclusively by another user or you need permission to view its data.
I'm fairly new to databases, VBA and Access so any help would be greatly appreciated.
Also I have been told that the above method of having an Excel front-end and Access back-end is not recommended but alot of the analysis they conduct is done through Excel, and the charts feature in Excel is much better than Access in my experience atleast; and that is also one of the requirements for this project.
Thank you advance!
Solution to your first problem:
Sorry to be the bearer of bad news, but your entire first module is unnecessary. Instead, try:
Go to Data->Import External Data->Import Data, select your Access file, select your table, and presto! done!
Right-click on your new "External Data Range" to see a number of options, some related to formatting. You can even keep the original cell formatting and just update the values. I do this all the time.
To update the Excel data table later, there is a "External Data Range" toolbar that allows you to refresh it as well as a "refresh all" option to refresh every table in the Excel file. (You can also automate this thru code. It'll take some trial and error, but you're definitely up to the task)
Regarding your second problem
I've never used it, but there is also a "New Web Query" option in there as well. I assume it can be manipulated and updated the same way.
And lastly
Your choice of the Excel front-end and the Access back-end sounds good for your needs. It gets the data to your analysts in a medium they are familiar with (Excel) while keeping the calculations out of the way in Access. Technically, you could try putting all your calculations in Excel, but that might the Excel file much bigger and slower to open.
Do the data entry/updating/reviewing in Access. One of Access' strengths is using forms that allow you to update the tables without any code. Then allow the users to easily export the data to Excel such as by clicking on some command buttons.
Modules: Sample Excel Automation - cell by cell which is slow
Modules: Transferring Records to Excel with Automation
nothing wrong in principle with the excel/access pairing. I'm not familiar with ADO (I use DAO), but your error message seems to be indicating that the path to the datasource is not fully formed; or you already have it opened and hence are locking it.

Manipulate a file in code (VB.NET) without executing the file's macros

I have an Excel file that has a bunch of VBA and macro code in it. When I open the file in Excel I can choose not to 'enable' them - so the values in the fields all stay as they were during the last save. I need to manipulate the values as they were last saved - so I don't want the macros (which look at the current date and update values accordingly) to run.
When I open it via our dot net code:
Dim oxlRep As Excel.Application
Dim oWBRep As Excel.Workbook
Dim oSheetRep As Excel.Worksheet
Dim oRngRep As Excel.Range
oxlRep.Open(path)
the vb code runs - throwing off the values. I've been looking for a way to open it without macros, or in 'secure' mode where the macros aren't run. If I simply double click the file and don't choose to enable macros the values are all there as I want them.
Usually we run this code within the month that the files are created, so we haven't seen this problem in the 3 or 4 years that it has been working. Now I need to go back to some of the old files and run some archival code...
Anyone have a suggestion?
Application.AutomationSecurity = msoAutomationSecurity.msoAutomationSecurityForceDisable
Try opening the workbook after this statement.
I think, this will disable macros at Application Level (not at workbook level)
Hope that helps.
Is ADO any use to you? I can only give a script example, i'm afraid.
strLinkFile = "C:\Docs\LTD.xls"
Set cn = CreateObject("ADODB.Connection")
cn.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & strLinkFile & ";" & _
"Extended Properties=""Excel 8.0;HDR=YES;"""
Set rs = CreateObject("ADODB.Recordset")
rs.Open "Select * from [Sheet1$A1:B5]", cn, adOpenStatic

Resources