Deleting empty worksheets - vb.net

I'm trying to write a code to delete empty worksheets in a workbook. So far I have been able to delete worksheets starting at the highest to the lowest using the code:
Dim i As Integer
Dim objExcel As Object = CreateObject("Excel.Application")
objExcel.Visible = True
objExcel.DisplayAlerts = False
Dim objWorkbook As Excel.Workbook = objExcel.Workbooks.Open(TextBox1.Text)
i = objWorkbook.Worksheets.Count
Do Until i = 2
objWorkbook.Worksheets(1).Delete()
i = i - 1
Loop
I had a look on the internet, but didn't find something that can be useful. Can anyone help me by guiding me to the right direction where I can obtain information on how to detect for empty worksheets in a single workbook using VB.net only.
Thank You

This should do the trick in vb.net
Private Sub DeleteBlankWorksheets(xlWorkBook As Excel.Workbook)
For i As Integer = xlWorkBook.Worksheets.Count To 1 Step -1
Dim ws As Excel.Worksheet = CType(xlWorkBook.Worksheets(i), Excel.Worksheet)
If Convert.ToInt64(ws.UsedRange.CountLarge) <= 1 Then
ws.Delete()
End If
Next
End Sub
Replace your entire loop with a call to this function, passing your objWorkBook object as the parameter.
Dim objExcel As Object = CreateObject("Excel.Application")
objExcel.Visible = True
objExcel.DisplayAlerts = False
Dim objWorkbook As Excel.Workbook = objExcel.Workbooks.Open(TextBox1.Text)
DeleteBlankWorksheets(objWorkbook)
'Add this to save the file
objWorkbook.Save()
objWorkbook.Close() 'closes the files
'If you have trouble with the file object being still opened, meaning you can see the EXCEL.exe in the task manager then add the following code
For Each instance As Process In Process.GetProcesses
If InStr(instance.MainWindowTitle, Textbox1.Text) <> 0 Then p.Kill()
Next
NOTE: It is better to make sure to dispose of all of your excel objects (applications, workbooks, worksheets, etc) than to kill processes. This will ensure all data is preserved as intended without side effects. If you find you have extra excel.exe instances running, make sure to double check everything is disposed and released properly.

This will do the job
Sub DeleteBlankWs()
Dim ws As Worksheet
For Each ws In Worksheets
If WorksheetFunction.CountA(ws.Cells) = 0 Then
Application.DisplayAlerts = False
ws.Delete
Application.DisplayAlerts = True
End If
Next ws
End Sub
I created an excel with 5 sheets, sheet 2 and 4 are empty, then I edited a micro and run it (F5 key or the green play icon)...

Related

Store all currently opened excel workbooks and open it later

I am currently facing a problem in which I want to:
1.Store all currently opened excel workbooks in a an array
2.Save and close the workbook
3.Open back all opened workbooks
4.Focus back to a specific workbook
The current code i have:
For Each wb In Application.Workbooks
wb.Save
Next wb
Works as expected but my different excel workbooks keeps 'flashing' which is kind of irritating, thus the need to save and close all.
I do understand that to focus back to a specific workbook u can use activate function. If i do an set array inside the 'For each loop', it will not work as it will become a double for loop.
As i'm new to VBA, i would really appreciate any input from you all.
Thank you!
I've given you two different options in this code. Either using a collection or an array.
You can step through a collection using For Each item in Collection loop while the array would need a For..Next loop.
Sub All_OpenWorkBooks_Collection()
Dim wrkBk As Workbook
''''''''''''''''''''''''''''''''''''''''''''''''''''''
'Add to a collection '
''''''''''''''''''''''''''''''''''''''''''''''''''''''
Dim vItem As Variant
Dim colWorkBooks As Collection
Set colWorkBooks = New Collection
For Each wrkBk In Workbooks
If wrkBk.Name <> ThisWorkbook.Name Then
colWorkBooks.Add wrkBk.FullName
wrkBk.Close SaveChanges:=True
End If
Next wrkBk
Set wrkBk = Nothing
For Each vItem In colWorkBooks
Workbooks.Open (vItem)
Next vItem
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'Set a reference to a specific workbook - can then use wrkBk to refer to it. '
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Set wrkBk = Workbooks("Copy (4) of New Microsoft Excel Worksheet.xlsx")
wrkBk.Activate
End Sub
'------------------------------------------------------------------------
Sub All_OpenWorkbooks_Array()
Dim wrkBk As Workbook
''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'Add to an array. '
''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Dim x As Long
Dim arrWrkBk() As Variant
ReDim arrWrkBk(1 To Workbooks.Count)
For x = Workbooks.Count To 1 Step -1
If Workbooks(x).Name <> ThisWorkbook.Name Then
arrWrkBk(x) = Workbooks(x).FullName
Workbooks(x).Close SaveChanges:=True
End If
Next x
For x = 1 To UBound(arrWrkBk)
If arrWrkBk(x) <> "" Then
Workbooks.Open (arrWrkBk(x))
End If
Next x
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'Set a reference to a specific workbook - can then use wrkBk to refer to it. '
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Set wrkBk = Workbooks("Copy (4) of New Microsoft Excel Worksheet.xlsx")
wrkBk.Activate
End Sub
Edit: Note I step backwards through the array loop - as it's counting open workbooks and closing them the number of open workbooks goes down as the loop progresses (so when it got to loop number 4 there's a good chance that workbook number 4 has already been closed).
Edit 2: The comment on workspaces may be just what you're after - I'd check that out first.
Would adding
.ScreenUpdating = False
before your loop help?
And
.ScreenUpdating = true
after to switch it back on.

How to define an object inside a for loop for excel vba

I want to import data from multiple workbooks, all from the same sheet index (3).
I'm new to vba, and I figured out how to open multiple files up, and also to copy data from one sheet to another sheet in a different workbook for a single file, but I can't seem to figure out how to do that for multiple files.
I highlighted where the error is, it tells me "object doesn't support this property or method"
Could you please help?
Thanks
Sub dataimport()
' Set Vars
Dim ArbinBook As Workbook, DataBook As Workbook
Dim i As Integer, j As Integer
Dim Caption As String
Dim ArbinFile As Variant, DataFile As Variant
' make weak assumption that active workbook is the target
Set DataBook = Application.ActiveWorkbook
' get Arbin workbook
Caption = "Please select an input file"
' To set open destination:
' ChDrive ("E")
' ChDir ("E:\Chapters\chap14")
' With Application
'Set "arbinfile" as variant, the "true" at end makes it into an array
ArbinFile = Application.GetOpenFilename(, , Caption, , True)
'Exit when canceled
If Not IsArray(ArbinFile) Then
MsgBox "No file was selected."
Exit Sub
End If
Dim targetSheet As Worksheet
Set targetSheet = DataBook.Sheets(1)
'Open for every integer i selected in the array "arbinfile"
For i = LBound(ArbinFile) To UBound(ArbinFile)
Set ArbinBook = Workbooks.Open(ArbinFile(i))
targetSheet.Range("A2", "G150").Value = ArbinBook.Sheets(3).Range("A2", "G150").Value
**ERROR at the line above**
Workbooks(DataSheet).Activate 'Reactivate the data book
Worksheets(1).Activate 'Reactivate the data sheet
ActiveWorkbook.Sheets(1).Copy _
after:=ActiveWorkbook.Sheets(1)
Workbooks(ArbinFile(1)).Activate 'Reactivate the arbin book(i)
ArbinBook.Close
Next i
Beep
End Sub
My instinct tells me that ArbinBook.Sheets(3) is a Chart-sheet, not a WorkSheet (or, at least, it is something other than a WorkSheet). It might be hidden as well, but it will still be indexed as (3).
If so, change Sheets(3) to Worksheets(3).
Added: BTW If true, this also demonstrates why using index-numbers is unreliable. If at all possible, refer to a worksheet by its name. (I appreciate that this may not always be possible.)
Added (from comments) There is nothing named DataSheet in your code. Add Option Explicit to the top of your module to indicate all such errors.
Try changing the line Set ArbinBook = Workbooks.Open(ArbinFile(i))
to Set ArbinBook = Workbooks(arbinfile(i))
I could be wrong, but I think it's trying to set your workbook object to become the action of opening another workbook, instead of labeling it as the workboook.
Sub Multiple()
Application.DisplayAlerts = False
Application.EnableEvents = False
Dim exlApp As Excel.Application
Dim exlWb1 As Excel.Workbook
Dim exlWb2 As Excel.Workbook
Dim exlWb3 As Excel.Workbook
Dim exlWs1 As Excel.Worksheet
Dim exlWs2 As Excel.Worksheet
Dim exlWs3 As Excel.Worksheet
Set exlApp = CreateObject("Excel.Application")
Set exlWb1 = exlApp.Workbooks.Open("C:\yourpath1\file1.xls")
Set exlWb2 = exlApp.Workbooks.Open("C:\yourpath2\file2.xls")
Set exlWb3 = exlApp.Workbooks.Open("C:\yourpath3\file3.xls")
Set exlWs1 = exlWb.Sheets("Sheet1")
Set exlWs2 = exlWb.Sheets("Sheet1")
Set exlWs3 = exlWb.Sheets("Sheet1")
exlWb1.Activate
exlWb2.Activate
exlWb3.Activate
'code
exlWb.Close savechanges:=True
exlWb.Close savechanges:=True
exlWb.Close savechanges:=True
Set exlWs1 = Nothing
Set exlWs2 = Nothing
Set exlWs3 = Nothing
Set exlWb1 = Nothing
Set exlWb2 = Nothing
Set exlWb3 = Nothing
exlApp.Quit
Set exlApp = Nothing
Application.EnableEvents = True
Application.DisplayAlerts = True
End Sub

Workbooks.Open returns different file than Filename

I am having the strangest problem. I was writing the below code on my laptop the other day and it worked fine. Now, I am testing it on my desktop and it's stopped working.
First, here's my code
Dim oApp As Application
Dim oWb As Workbook
Set oApp = New Application
oApp.Visible = True
Set oWb = oApp.Workbooks.Open(Filename:="C:\myFile.xlsx", ReadOnly:=True)
debug.print oWb.name
'returns "SOLVER.XLAM"
' "SOLVER.XLAM" is not "myFile.xlsx'
debug.print oApp.Workbooks.Count
'returns 1
debug.print oApp.Workbooks(1).name
'returns "myFile.xlsx"
Now, I know that solver is an add in, and it gets loaded in the new application upon creating it... but how does it perform this switcheroo? I can still get to the correct file, but I don't want to risk it on the coincidence that there is only 1 file in my Application object (or that the first file is the one I loaded)
Additional Info
I am calling executing this macro from within an excel instance and I wish to open a separate excel instance and then open particular workbook ("C:\myFile.xlsx") inside that other instance.
The key problem I'm having is that when I open the other instance and then add the workbook and set it to my oWb variable... somehow, when I later call that oWb variable it refers to something different from what I had set it to.
'This is how it makes me feel:
Dim x As Integer
x = 5
Debug.Print x
' 12
I think if you just refine your code a bit to ensure you are doing exactly what you want, you will be fine. Since it's unclear whether you are calling the code from within Excel or another MS Office Application, I placed to subs below.
Run this if running it in Excel:
Option Explicit
Sub insideXL()
Dim oWb As Workbook
Set oWb = Workbooks.Open("C:\myFile.xlsx", ReadOnly:=True)
Debug.Print oWb.Name
Debug.Print Workbooks.Count
Debug.Print Workbooks(1).Name
oWb.Close false
Set oWb = Nothing
End Sub
Run this if running in another program. I use early binding, but you could use late binding as well, if you wish:
Sub outsideXL()
'make sure Microsoft Excel X.X Object Library is checked in Tools > References
Dim oApp As Excel.Application
Set oApp = New Excel.Application
Dim oWb As Excel.Workbook
Set oWb = oApp.Workbooks.Open("C:\myFile.xlsx", ReadOnly:=True)
oApp.Visible = True
Debug.Print oWb.Name
Debug.Print Workbooks.Count
Debug.Print Workbooks(1).Name
oWb.Close = True
Set oWb = Nothing
Set oApp = Nothing
End Sub
I found that this (which worked in 2007):
wb = excel.Workbooks.Open(filename, False, True)
needs to be written
excel.Workbooks.Open(filename, False, True)
wb = excel.ActiveWorkbook
for 2010

Opening a workbook with VBA/macro is making it read only?

I would like my code to open a workbook (always the same one), detect the first free row, write to just two cells in that row, and then save/close the workbook. This seems like a simple problem, but the macro seems to be opening a copy of the file, and then locking it for editing.
Can you see any errors in my open code? I know that the file opens and that the row search works, but then it 1. never writes to the cells, and 2. locks the file.
Function WriteToMaster(Num, Path) As Boolean
'Declare variables
Dim xlApp As Excel.Application
Dim wb As Workbook
Dim ws As Worksheet
Dim infoLoc As Long
Set xlApp = New Excel.Application
'Specifies where the Master Move Key is stored
Set wb = xlApp.Workbooks.Open("DOC LOCATION")
Set ws = wb.Worksheets("Sheet1")
'Loop through cells, looking for an empty one, and set that to the loan number
infoLoc = firstBlankRow(ws)
MsgBox "First blank row is " & infoLoc & ". Num is " & Num
ws.Cells(infoLoc, 1).Value = Num
ws.Cells(infoLoc, 2).Value = Path
'Save, close, and quit
wb.Save
wb.Close
xlApp.Quit
'Resets the variables
Set ws = Nothing
Set wb = Nothing
Set xlApp = Nothing
'pieces of function from http://p2p.wrox.com/vb-how/30-read-write-excel-file-using-vb6.html
End Function
Thank you again, stackoverflow <3
Do you need to open a new excel app just to open a workbook?
Can't you just do something like this:
Sub Macro1()
Dim wkb As Workbook
Workbooks.Open Filename:="\User Documents$\bob\My Documents\workbook_open_example.xlsx"
Set wkb = Workbooks("workbook_open_example.xlsx")
End Sub

Excel worksheets in vb.net

Is there a way when to make the current worksheet your on in excel to be the worksheet shown when changing worksheets in vb.net? Say I'm on worksheet 1 and change it to worksheet 2 through vb.net, If I enter in data it will show up on worksheet two but in order to see the data I have to physically go to the excel file and select worksheet 2 in order to change the actually worksheet page being displayed.
Tried this code and it seems to work on my side. The trick is the method sheet.Activate()
Sub Main
Dim excelApp as Microsoft.Office.Interop.Excel.Application = _
new Microsoft.Office.Interop.Excel.Application()
Try
Dim inFile As String = "D:\temp\test.xls"
' Show excel '
excelApp.Visible = true
Dim excelWorkbook As Microsoft.Office.Interop.Excel._Workbook = _
excelApp.Workbooks.Open(infile)
Dim x as Integer
for x = excelApp.Sheets.Count to 1 step -1
Dim sheet as _Worksheet = CType(excelApp.Sheets(x), _Worksheet)
sheet.Activate() ' Activate the sheet'
Thread.Sleep(5000) ' Sleep for 5 seconds to see the sheet'
Next
Finally
if excelApp IsNot Nothing then
excelApp.DisplayAlerts = false
'excelApp.Quit(); 'remove the comment to close excel'
End if
End try
End Sub