How to get the Active Workbook? - excel

I'm trying to get the Workbook in my application(VSTO) like this :
ExcelViewModel mb = new ViewModels.ExcelViewModel();
string NameBox = mb.Workbooks.First().Name;
So when Excel open, it already have the default workbook : Book1.xlsx i open for example a second workbook(example.xlsx) but my string NameBox return the "Book1". How can i get the active Workbook? for my example the "example.xlsx" one.
The ExcelViewModel just return me an ObservableCollection of all Workbooks.
Thank you.

I found it :
Globals.ThisAddin.Application.ActiveWorkbook.Name

Related

Openpyxl created excel file with table causes file that requires recovery error

I have been testing adding a table to a worksheet using openpyxl, but I get the error below when I try to open it. The file opens, but the formatting isn't correct. After hitting recover, excel reports that there was an issue with the table xml. Is there a workaround/fix for this?
The code I'm using:
import openpyxl
from openpyxl import Workbook
from openpyxl.worksheet.table import Table, TableStyleInfo
xl_file_name = "new_test.xlsx"
wb = Workbook()
ws = wb.worksheets[0]
ws.title = "Table_Sheet"
headers = ["header1","header2","header3"]
for col in range(1,len(headers)+1):
for row in range(1,5):
if row == 1:
ws.cell(row,col).value = headers[col-1]
else:
ws.cell(row,col).value = str(row)
tbl = Table(displayName="Tbl1",ref="A1:C4")
style = TableStyleInfo(name="TableStyleMedium9", showFirstColumn=False, showLastColumn=False, showRowStripes=True, showColumnStripes=True)
tbl.tableStyleInfo = style
ws.add_table(tbl)
wb.save("new_test.xlsx")
Your name for the table is causing the problem. Run the same code with displayName="Tbl" or displayName="Tbl_1" instead, and you'll see it works fine. I'm not 100% sure, but I think the cause of the issue is that the name you give conflicts with the formatting for a possible cell reference of TBL1.
For me the following worked:
Change the Workbook as you wish (only Data no formatting)
Save the Workbook (If you would try to open it here it will display the error message)
Close the Workbook
Open the Workbook again (I think here Excel fixes the issue automatically)
Insert necessary formatting commands
Save the workbook
Close the Workbook
Or, as code:
import openpyxl
workbook = openpyxl.load_workbook(Source_Path)
##your code appending and deleting values - which I think sometimes causes the errors
workbook.save(Destination_Path)
workbook.close
#Now open it again
workbook = openpyxl.load_workbook(Destination_Path)
#Your Code to format
workbook.save(Destination_Path)
workbook.close
Now you should be able to open the Excel file without an error.
I've had the same error message.
I was creating tables with numbers at the start of the name, so I changed that code to add t_ at the beginning, so
table_name = "112MHZ_data"
became
table_name = "t_112MHZ_data"
And that solved it for me.

Why is my Excel file empty after writing content to cells using Microsoft.Office.Interop.Excel?

I'm using Microsoft.Office.Interop.Excel to write an Excel file. The code below is not working:
var excel = new Microsoft.Office.Interop.Excel.Application();
var workbook = excel.Workbooks.Add(Type.Missing);
var worksheet = (Microsoft.Office.Interop.Excel.Worksheet)workbook.ActiveSheet;
worksheet.Name = "sheet1";
worksheet.Cells[1,1] = "top left";
worksheet.Cells[1,2] = "top right";
worksheet.Cells[2,1] = "bottom left";
worksheet.Cells[2,2] = "bottom right";
workbook.SaveAs("temp.xlsx");
workbook.Close();
excel.Quit();
It produces an Excel file but it is empty. I'm expecting to see the text "top left", "top right",... in the first 2 by 2 cells. But I see nothing.
Why is it not writing content to my worksheet?
You can find my code at github: https://github.com/gibran-shah/Image2Excel
Perhaps this link might help you: http://csharp.net-informations.com/excel/csharp-create-excel.htm
According to the link above, try using:
var worksheet = (Microsoft.Office.Interop.Excel.Worksheet)workbook.get_Item(1);
To troubleshoot further, I would choose some other name for the sheet, and check that the name is actually being set by opening the workbook and observing the name in the sheet's tab. This would ensure you are indeed adding data to the sheet that you think you are.

AutoHotkey's ComObjActive handle to specific Worksheet

The simplest way to create a handle to your currently active Excel sheets in your .ahk script is:
Xl := ComObjActive("Excel.Application")
Nonetheless, if one switches to another workbook, this becomes the new "currently active sheet" and AutoHotkey tries to use methods for sheets and cells on the new workbook through COM: of course scripts designed to work with specific sheets and cells don't work anymore on a different workbook.
Do you know how to create COM handles to specific workbooks instead of currently active sheet?
The goal should be to allow the user to loop between workbooks without Xl object losing its previous handle and going to a new one.
Example
Open an Excel workbook from scratch and type 1234 in cell A1 of sheet named "Sheet1"; then create a new .ahk script with the following content:
#Persistent
Xl := ComObjActive("Excel.Application")
SetTimer, xlRead, 5000
Return
xlRead:
{
value := Xl.Sheets("Sheets1").Range("A1").Value
MsgBox, %value%
}
Return
Script above should display "1234" in a message box every 5 seconds.
While that is running, open a new workbook and type 5678 in cell A1 of sheet named "Sheet1" and wait for 5 seconds: according to my trials, AutoHotkey should just switch the handle to the new active sheet and show a message box whose content is "5678".
Any way to keep it linked to the first sheet? Of course assume one can save Excel files to hard disk with proper names which COM can refer to.
one way is to store the active workbook object in a variable like this
#Persistent
oExcel := ComObjActive("Excel.Application")
this_book := oExcel.ActiveWorkbook
SetTimer, xlRead, 10000
Return
xlRead:
{
value := this_book.Sheets(1).Range("A1").Value
MsgBox, %value%
}
Return
2nd way is to use ComObjGet with the full name of the active workbook if you know it before hand no need for the ControlGetText command just use the workbooks full name
#Persistent
SetTitleMatchMode, 2
ControlGetText, WorkBookName, Excel71, Microsoft Excel
oWorkbook := ComObjGet(WorkBookName)
SetTimer, xlRead, 10000
Return
xlRead:
{
value := oWorkbook.Sheets(1).Range("A1").Value
MsgBox, %value%
}
Return
You can also use ComObjGet with the full path of an excel file it will return the workbook object
#Persistent
fileselectfile, path
oWorkbook := ComObjGet(path)
SetTimer, xlRead, 10000
Return
xlRead:
{
value := oWorkbook.Sheets(1).Range("A1").Value
MsgBox, %value%
}
Return
Hope this helps you do what you need

importing data from many workbooks in different folders

I am looking to import/copy data from many workbooks into a summary workbook. The workbooks are arranged in different sub-folders, I.e
C:\data1\results_2001.xlm
C:\data2\results_2002.xlm
C:\data3\results_2003.xlm
The names are similar but differ slightly to differentiate them. At present, I import the files individually, and I want to automate the process. The results files (above) are amongst other excel files so I cannot target them by file type.
How would I import these files by partial file name?
One option is to create an array of the filepaths to your excel sheets and then loop over the array and get the data you want into your summary sheet.
Sub CreateSummary()
Dim wkbs() As Variant, wkb As Integer, owb As Workbook
wkbs = Array("C:\data1\results_2001.xlm", "C:\data2\results_2002.xlm", "C:\data3\results_2003.xlm")
For wkb = 0 To UBound(wkbs)
Set owb = Application.Workbooks.Open(wkbs(wkb)) //Open each workbook
With owb
//Get the data you want into your summary workbook
.Close
End With
Next wkb
End Sub
Another way, especially if only a one time operation: Go into Cmd.exe, do a Dir for the files you're looking for, and send it to a text file (eg, something like dir c:\results_*.xlm /s /b > c:\myList.txt). Then import the text file to your worksheet, step thru each cell in the list, opening each workbook in turn.
You can do it in any languages, but for you who is asking this question, i think it's gonna be a little challenging, so here is what you need to do :
create a function that will list files/folders from given path
loop through all items found, if it's a folder , recursive it
if the item fits your target(name, extension, ...) , read it and load the content to the summary
something like this, i believe you will achieve this easily using VBA, look here
Literally, it will be like this, please note that this is not valid code, just something i write down to help you figure it out :
function loopthepath (string pathtoloop)
foreach(dirItem item in pathtoloop.getdirItem)
{
if (item is folder)
{
loopthepath(pathtoloop + item)
}
else
{
if (item fits mydescription)
{
load the content to the summary
}
}
}

How to add more than 3 sheets to an excel workbook from within MATLAB

How do I add more sheets to an excel workbook from within matlab?
I set up the workbook like so (based on code I got from someone else's post in this forum):
%# create Excel COM Server
Excel = actxserver('Excel.Application');
Excel.Visible = true;
%# create new XLS file
wb = Excel.Workbooks.Add();
wsheet=1;
wb.Sheets.Item(wsheet).Activate();
That's fine. Then later on inside the loop I open a new sheet after so many loops:
...
if loop==sheetlimit,
wsheet=wsheet+1;
wb.Sheets.Item(wsheet).Activate();
end
This works up to sheet 3. But when wsheet=4 I get this error message:
??? Invoke Error, Dispatch Exception: Invalid index.
Error in ==> filename at 97
wb.Sheets.Item(wsheet).Activate();
Appreciate any help. Thanks.
I don't know Matlab but I would be surprised if wb.Sheets.Item(wsheet).Activate(); is actually adding any new worksheets. Most likely it is selecting / activating each worksheet in your wb workbook and your default Excel template has three worksheets. Hence why it errors when it gets to more than three.
Something like this might add a new Excel worksheet:
wb.sheets.Add();
Aargh - comment formatting completely messed up - I'll re-enter it as an new answer
Yes wb.sheets.Add(); will work. You can query the available methods of an interface like this:
methods(wb.sheets)
which gives:
Methods for class Interface.000208D7_0000_0000_C000_000000000046:
Add FillAcrossSheets PrintOut addproperty events loadobj set
Copy Item PrintPreview delete get release
Delete Move Select deleteproperty invoke saveobj

Resources