I keep getting Error 1004. I'm not sure how else to declare my object in order to avoid this error:
Sub DeleteBlank()
Dim wb As Workbook
Set wb = ActiveWorkbook
Dim ws As Worksheet
Set ws = wb.Worksheets("Sheet1")
ws.Activate
'Delete Blank Columns
For col = 1 To 4
If WorksheetFunction.CountA(ws.Columns(i)) = 0 Then
ws.Columns.Delete
End If
Next col
End Sub
Step backwards and use col not i. Also, can wrap in a With.
Option Explicit
Sub DeleteBlank()
Dim wb As Workbook
Set wb = ActiveWorkbook
Dim col As Long
Dim ws As Worksheet
Set ws = wb.Worksheets("Sheet1")
With ws
For col = 4 To 1 Step -1
If WorksheetFunction.CountA(.Columns(col)) = 0 Then
.Columns(col).Delete
End If
Next col
End With
End Sub
Related
I have created a Workbook that is used in various different computers.
Sometimes I add features to it and I would like to easily update it.
The idea is whenever I have a new version of it, I take it to a new computer, save in a temp file and copy the sheets where the data is stored.
Based on the answers I have edit my first draft to: (I didn't know that both workbooks needed to be opened at the same time)
Private Sub CommandButton1_Click()
Dim sh As Worksheet
Dim ws As Worksheet
Dim wb As Workbook
Dim wn As Workbook
Set wn = Workbooks("Reception")
Set wb = Workbooks("Reception2")
With wb
.Sheets("Pass").Range("A1") = "flh"
For Each ws In .Worksheets
Select Case .Name
Case "Formularios", "Coordenador", "LookupList", "Pass"
'Do nothing
Case Else
ws.Delete
End Select
Next ws
End With
With wn
For Each sh In .Worksheets
Select Case .Name
Case "Formularios", "Coordenador", "LookupList", "Pass"
'Do nothing
Case Else
sh.Copy After:=wb.Sheets(wb.Sheets.Count)
End Select
Next sh
End With
End Sub
Case at moment is not working and macro deletes every sheet no matter the name
Thank you all for the feedback
You can find the temp folder by using Environ("temp"), but from your code I'm not sure this is the folder you're using.
This code has a couple of functions to check if the workbook exists and is already open. One other bit of code I'd add is to disable any code in Reception.xlsm from firing when it's opened.
Public Sub MyProcedure()
Dim ws As Worksheet
Dim wb As Workbook
Dim wn As Workbook
Dim Rec1Path As String
Dim Rec2Path As String
Rec1Path = "c:\save\Reception.xlsm"
Rec2Path = "c:\temp\Reception2.xlsm"
'Open or set a reference to Reception.xlsm.
If WorkBookExists(Rec1Path) Then
If WorkBookIsOpen(Rec1Path) Then
'Don't need path for open workbook, just name.
'InStrRev finds last occurrence of "\" (same as InStr, but in Reverse).
Set wn = Workbooks(Mid(Rec1Path, InStrRev(Rec1Path, "\") + 1))
Else
Set wn = Workbooks.Open(Rec1Path)
End If
End If
'Open or set a reference to Reception2.xlsm.
If WorkBookExists(Rec2Path) Then
If WorkBookIsOpen(Rec2Path) Then
Set wb = Workbooks(Mid(Rec2Path, InStrRev(Rec2Path, "\") + 1))
Else
Set wb = Workbooks.Open(Rec2Path)
End If
End If
With wb
.Worksheets("Pass").Range("A1") = "flh"
For Each ws In .Worksheets
Select Case .Name
Case "Formularios", "Coordenador", "LookupList", "Pass"
'Do nothing
Case Else
'You don't really need the count of worksheets if you can guarantee
'you're not going to try and delete the last remaining sheet.
If .Worksheets.Count > 1 Then
Application.DisplayAlerts = False
ws.Delete
Application.DisplayAlerts = True
End If
End Select
Next ws
End With
With wn
'Re-using the ws variable.
For Each ws In .Worksheets
Select Case .Name
Case "Formularios", "Coordenador", "LookupList", "Pass"
'Do nothing
Case Else
ws.Copy After:=wb.Sheets(wb.Sheets.Count)
End Select
Next ws
End With
End Sub
Public Function WorkBookExists(sPath As String) As Boolean
WorkBookExists = Dir(sPath) <> ""
End Function
Public Function WorkBookIsOpen(FullFilePath As String) As Boolean
Dim ff As Long
On Error Resume Next
ff = FreeFile()
Open FullFilePath For Input Lock Read As #ff
Close ff
WorkBookIsOpen = (Err.Number <> 0)
On Error GoTo 0
End Function
Is the workbook open when you try to 'SET' it? If not you will need to open it as such:
Dim wb As Workbook
Set wb = Workbooks.Open("c:\temp\Reception.xlsm")
With some more googling I was able to craft the code that I wanted in the end.
Here is the answer for the curious or for other people looking to do the same:
Private Sub CommandButton1_Click()
Dim sh As Worksheet
Dim ws As Worksheet
Dim LastRow As Long
Dim LastCol As Long
Dim j As Long
Dim Rng As Range
Dim wb As Workbook
Dim wn As Workbook
Set wn = Workbooks("Reception")
Set wb = Workbooks("Reception2")
With wb
.Sheets("Pass").Range("A1") = "flh"
For Each ws In .Worksheets
Select Case ws.Name
Case "Formularios"
'Do nothing
Case "Coordenador"
'Do nothing
Case "LookupList"
'Do nothing
Case "Pass"
'Do nothing
Case Else
With ws
LastRow = .Range("A" & .Rows.Count).End(xlUp).Row
LastCol = .Cells(1, .Columns.Count).End(xlToLeft).Column
Set Rng = .Range(.Cells(2, 1), .Cells(LastRow, LastCol))
Rng.ClearContents
End With
End Select
Next ws
End With
With wn
For Each sh In .Worksheets
Select Case sh.Name
Case "Formularios"
'Do nothing
Case "Coordenador"
'Do nothing
Case "LookupList"
'Do nothing
Case "Pass"
'Do nothing
Case Else
For j = 1 To wb.Sheets.Count
If sh.Name = wb.Worksheets(j).Name Then
On Error Resume Next
sh.Range("A:J").Copy wb.Worksheets(j).Range("A1")
End If
Next j
End Select
Next sh
End With
Application.CutCopyMode = False
End Sub
Thanks to #Darren Bartrup-Cook for the help.
I am using two workbooks at a time. The first workbook is the current workbook and the second will be opened while programming execution. I have made the global objects of the workbooks and worksheets. I'm having issues with using the worksheets simultaneously. The error is ERROR: object variable or with block variable, not set. I have mentioned the error in the comment in the second subroutine.
Dim WB As Workbook
Dim WB2 As Workbook
Dim WKS As Worksheet
Dim WKS2 As Worksheet
Sub Button1_Click()
Dim fd As Office.FileDialog
Set fd = Application.FileDialog(msoFileDialogFilePicker)
Set WB = ThisWorkbook
WB.Activate
fd.AllowMultiSelect = False
fd.Title = "Provide a title here."
fd.InitialFileName = ThisWorkbook.Path
If fd.Show() = True Then
strFile = fd.SelectedItems(1)
Set WB2 = Workbooks.Open(strFile)
Set WSK2 = WB2.Sheets("Schweitzer Analysis")
CalculateGrades
Else
MsgBox ("No file selected")
End If
End Sub
Sub CalculateGrades()
' first clear the contents where grades results can appear
clearGradesContents
Dim index As Integer ' for current sheet
Dim index2 As Integer ' for student sheet
Dim countCorrect As Integer ' to count no of correct answers
index = 2
index = 8
countCorrect = 0
' this first error here
' ERROR: object variable or with block variable not set
Set WKS = WB.ActiveSheet
Do While index <= 21
' the SECOND error shows here
If WKS.Cells(index, 2) = WKS2.Cells(index2, 3) Then
Count = Count + 1
Else
WKS.Cells(index, 5) = WKS2.Cells(index2, 3)
End If
If WKS.Cells(index, 3) = WKS2.Cells(index2, 4) Then
Count = Count + 1
Else
WKS.Cells(index, 6) = WKS2.Cells(index2, 4)
End If
index2 = index2 + 1
index = index + 1
Loop
End Sub
Sub clearGradesContents()
Range("E2:F21").Select
Selection.ClearContents
Range("I2:I3").Select
Selection.ClearContents
End Sub
EDIT: sorry for the previous answer, I hadn't seen your global declarations on top and I was sure it was because you hadn't declare it.
I think the issue is the following:
[...]
Set WB = ThisWorkbook
WB.Activate '<-- WB is the active workbook now
[...]
Set WB2 = Workbooks.Open(strFile) '<-- WB2 is the active workbook now!
Set WSK2 = WB2.Sheets("Schweitzer Analysis")
CalculateGrades '<-- going to next macro
[...]
Set WKS = WB.ActiveSheet '<-- ERROR: WB2 is the active workbook. WB can't have an active sheet if it's not the active workbook
Then of course, being WKS not correctly set, you can't execute this:
If WKS.Cells(index, 2) = WKS2.Cells(index2, 3) Then
I have no way to test it now, but I think that should be the issue.
To solve it,
If you really need WKS to be the ActiveSheet
Dim activeSheetName As String
...
Sub Button1Click()
...
Set WB = ThisWorkbook
WB.Activate
activeSheetName = WB.ActiveSheet.Name
...
End Sub
Sub CalculateGrades()
...
Set WKS = WB.Sheets(activeSheetName)
...
If you already know the name of the sheet you need
Just write:
Set WKS = WB.Sheets("your sheet")
instead of
Set WKS = WB.ActiveSheet
I'm trying to assign the code name of a worksheet to a vriable.
Some times it gets the code name correctly, and sometimes it doesn't, the variable stays null.
Dim sCodeName As String
sCodeName = Worksheets(atar).CodeName
atar is a variable that contains the worksheet name.
When i stop the code running, and coninue in debug mode, it works fine.
What can be the reason?
Worksheets without qualification refers to same as ActiveWorkbook, perhaps you're assuming too much about which workbook is active in some instances.
It is recommended to fully qualify Worksheets. So get a reference to a Workbook object , say wbFoo and then use sCodeName = wbFoo.Worksheets(atar).CodeName
You could try something like the code below to verify that atar does exist in one of the worksheet names in ThisWorkbook.
Option Explicit
Sub GetWorksheetCodeName()
Dim sCodeName As String
Dim atar As String
Dim Sht As Worksheet
'atar = "Sheet3" '<-- for tests only
' loop through all worksheets in ThisWorkbook
For Each Sht In ThisWorkbook.Worksheets
If Sht.Name Like atar Then
sCodeName = Worksheets(atar).CodeName
Exit For
End If
Next Sht
End Sub
CREATE MULTIPLE WORKSHEET BUT SOMETIMES NOT WORK WITH MACRO FROM WORKSHEET ONLY WORK WITH VBA CODE RUN
Sub WSCreate()
Dim WSA As String
Dim WSB As String
Dim WS As Worksheet
WSA = "SheetA"
WSB = "SheetB"
Application.DisplayAlerts = False
On Error Resume Next
'DELETE MULTIPLE WORKSHEETS (IF Already Exist)
Set WS = Nothing
Set WS = Sheets(WSA)
WS.Delete
Set WS = Nothing
Set WS = Sheets(WSB)
WS.Delete
Set WS = Nothing
'CREATE MULTIPLE WORKSHEETS
With Application.ThisWorkbook
.Worksheets.Add.Name = WSA 'WSA = SheetA
.VBProject.VBComponents(Worksheets(WSA).CodeName).Name = WSA
.Worksheets.Add.Name = WSB 'WSB = SheetB
.VBProject.VBComponents(Worksheets(WSB).CodeName).Name = WSB
End With
If Err <> 0 Then Exit Sub
End Sub
Hello I'm trying to copy columns C, R, W,X from file 1 to file 2 with below code but keep getting an error. My VBA knowledge isn't that good yet but probably has to do with the range setting? I've tried multiple ways but can't get it to work.
Am I using the right setting or should I use another action to get the specific columns?
Sub PFS()
Dim wbCopy As Workbook
Dim wsCopy As Worksheet
Dim rngCopy As Range
Dim wbPaste As Workbook
Dim wsPaste As Worksheet
Dim rngPaste As Range
Set wbPaste = ActiveWorkbook
Set wbCopy = Workbooks.Open("path to copy")
Set wsCopy = wbCopy.Worksheets("Blad1")
Set rngCopy = wsCopy.Range("d, e").EntireColumn
Set wsPaste = wbPaste.Worksheets("PFS")
Set rngPaste = wsPaste.Range("a1")
rngCopy.Copy
rngPaste.PasteSpecial
Workbooks.Application.CutCopyMode = False
Application.DisplayAlerts = False
wbCopy.Save
wbCopy.Close
End Sub
Solutions to copy entire column.
Sub copy()
Dim wb As Workbook
Dim wbNew As Workbook
Dim ws As Worksheet
Dim wsNew As Worksheet
Set wb = ActiveWorkbook
Set ws = wb.Sheets("old")
Set wbNew = Workbooks("Book.xlsx")
Set wsNew = wbNew.Sheets("new")
ws.Columns(3).copy
wsNew.Columns(3).Insert Shift:=xlToRight
ws.Columns(18).copy
wsNew.Columns(18).Insert Shift:=xlToRight
ws.Columns(23).copy
wsNew.Columns(23).Insert Shift:=xlToRight
ws.Columns(24).copy
wsNew.Columns(24).Insert Shift:=xlToRight
Set wsNew = Nothing
Set wbNew = Nothing
Set ws = Nothing
Set wb = Nothing
End Sub
The worksheet name may change. Because of that I want to set the worksheet object based on the worksheet's codename. How can I do this?
My best attempt so far is:
Sub UpdateNameDropdown()
Dim wksName As String
wksName = ThisWorkbook.Sheets(Sheet16).Name
Dim wks As Worksheet
Set wks = Sheets(wksName)
End Sub
But I get a type mismatch error on the row wksName = ThisWorkbook.Sheets.Sheet16.Name
This?
Sub Sample()
Dim wks As Worksheet
Set wks = Sheet16
With wks
Debug.Print .Name
'~~> Do what you want
End With
End Sub
This uses the codename as a String
Sub CodeIt()
Dim CodeName As String
CodeName = "Sheet1"
Dim WS As Worksheet, GetWorksheetFromCodeName As Worksheet
For Each WS In ThisWorkbook.Worksheets
If StrComp(WS.CodeName, CodeName, vbTextCompare) = 0 Then
Set GetWorksheetFromCodeName = WS
Exit For
End If
Next WS
MsgBox GetWorksheetFromCodeName.Name
End Sub
Thank you Gary's Student. I midified your function to the following:
Function GetWorksheetFromCodename(codeName As String) As Worksheet
Dim wks As Worksheet
For Each wks In ThisWorkbook.Worksheets
If StrComp(wks.codeName, codeName, vbTextCompare) = 0 Then
Set GetWorksheetFromCodename = wks
Exit For
End If
Next wks
End Function