I have a MS Excel spreadsheet which does some complex computations. I’d like to create a script which will create a CSV file with the results obtained from the spreadsheet.
I could rewrite the logic from the spreadsheet in my programming language (for example Ruby, but I’m open to use a different language), but then I would have to update my code whenever someone changes the logic in the spreadsheet. Is it possible to use a MS Excel spreadsheet as a black box, a computation engine, which can be invoked from my code? Then I would only have write the CSV part and input data download in my code, the whole computation logic could stay in the spreadsheet and could be easily updated.
Ideally, I don’t want to add any CSV generation or data download code to the spreadsheet, because it’s used by domain-experts (not programmers). Additionally, I have to download some data from the Internet and pass it to the spreadsheet as the input values. I’d like to keep that part of the code externally, in a version control system like Git. One additional note is that the spreadsheet uses the Solver Excel plugin.
Any help how to do that would be very appreciated.
To manipulate an Excel spreadsheet using Ruby, you may want to use win32ole
Here’s a sample script:
data = [["Hello", "World"]] # Require the WIN32OLE library require 'win32ole' # Create an instance of the Excel application object xl = WIN32OLE.new('Excel.Application') # Make Excel visible xl.Visible = 1 # Add a new Workbook object wb = xl.Workbooks.Add # Get the first Worksheet ws = wb.Worksheets(1) # Set the name of the worksheet tab ws.Name = 'Sample Worksheet' # For each row in the data set data.each_with_index do |row, r| # For each field in the row row.each_with_index do |field, c| # Write the data to the Worksheet ws.Cells(r+1, c+1).Value = field.to_s end end # Save the workbook wb.SaveAs('workbook.xls') # Close the workbook wb.Close # Quit Excel xl.Quit
To work out more complicated code, just record a macro of what you want to do, and then look at the code of your macro, and convert it from VB into Ruby.