Looping withing worksheets using AND condition - excel

I have a VBA macro to check the existing 10 worksheets in the workbook and perform an analysis as shown below. I want to loop this code to do the analysis for 100 worksheets using For loop. I am stuck on how to combine AND condition and for loop? Help will be appreciated.
I have tried to use the for loop but failed.
Sub Mostoccurence()
'
' Mostoccurence Macro
'
'
Sheets.Add After:=ActiveSheet
Sheets("Sheet11").Select
Sheets("Sheet11").Name = "analysis"
Range("A1").Select
ActiveCell.FormulaR1C1 = _
"=AND(Sheet1!RC=1,Sheet2!RC=1,Sheet3!RC=1,Sheet4!RC=1,Sheet5!RC=1,Sheet6!RC=1,Sheet7!RC=1,Sheet8!RC=1,Sheet9!RC=1,Sheet10!RC=1)"
End Sub

Try something like this:
Option Explicit
Sub AddSheetCompare()
Dim oAnalysisSht As Worksheet
Dim oLoopSht As Worksheet
Dim lRow As Long
On Error Resume Next
Set oAnalysisSht = Worksheets("Analysis")
On Error GoTo 0
If oAnalysisSht Is Nothing Then
Set oAnalysisSht = ActiveWorkbook.Worksheets.Add(ActiveWorkbook.Worksheets(1))
oAnalysisSht.Name = "Analysis"
oAnalysisSht.Range("A1").Value = "Result of all worksheets"
oAnalysisSht.Range("A3").Value = "Worksheet Results"
End If
lRow = 3
For Each oLoopSht In Worksheets
If Not oLoopSht.Name = oAnalysisSht.Name Then
lRow = lRow + 1
oAnalysisSht.Range("A" & lRow).Formula = "='" & oLoopSht.Name & "'!A1=1"
End If
Next
oAnalysisSht.Range("A2").Formula = "=AND(A4:A" & lRow & ")"
End Sub

Related

How do I modify this vba to copy column width and conditional formatting to an active sheet?

I am new to VBA.
Thank you for your time. I have been Googling for 2 days and always get an error.
I have two sheets
Projects ( where I will store project names) and
Template (where new projects will be created using the "template" sheet)
I have 2 issues I am trying to solve :
How do I copy the format on an active sheet including conditional formatting and column width. PasteSpecial already copies all the colour design but not the column width/conditional formatting
When I run the code it creates a new sheet called Project Name,not sure where that is coming from.
This is the code I am using:
Sub Copy()
Sheets("Template").Range("A1:O100").Copy
ActiveSheet.PasteSpecial
End Sub
<<<<<<<<<<<<<<<<<<<<<<
I want to generate a project name, make sure it does not exist(no duplicate), open a new sheet and copy the template from "template".
The full codes is:
RunAll()
CreateProjectName
CreateNewTab
CopyPaste
End Sub
Dim AddData As Range
Dim AddName As String
Set AddData = Cells(Rows.Count, 4).End(xlUp).Offset(1, 0)
AddName = InputBox("Enter Project Name do not input manually", "Project Monitor")
If AddName = "" Then Exit Sub
AddData.Value = AddName
AddData.Offset(0, 1).Value = Now
End Sub
Function SheetCheck(sheet_name As String) As Boolean
Dim ws As Worksheet
SheetCheck = False
For Each ws In ThisWorkbook.Worksheets
If ws.Name = sheet_name Then
SheetCheck = True
End If
Next
End Function
Sub CreateNewTab()
Dim sheets_count As Integer
Dim sheet_name As String
Dim i As Integer
sheet_count = Range("D3:D1000").Rows.Count
For i = 1 To sheet_count
sheet_name = Sheets("Projects").Range("D3:D1000").Cells(i, 1).Value
If SheetCheck(sheet_name) = False And sheet_name <> "" Then
Worksheets.Add(After:=Sheets("Projects")).Name = sheet_name
End If
Next i
End Sub
Sub CopyPaste()
Sheets("Template").Range("A1:o100").Copy
ActiveSheet.PasteSpecial
End Sub
Option Explicit
Sub AddProject()
Dim ws As Worksheet, NewName As String
NewName = InputBox("Enter Project Name do not input manually", "Project Monitor")
' checks
If NewName = "" Then
MsgBox "No name entered", vbCritical
Exit Sub
Else
' check sheet not existing
For Each ws In ThisWorkbook.Sheets
If UCase(ws.Name) = UCase(NewName) Then
MsgBox "Existing Sheet '" & ws.Name & "'", vbCritical, "Sheet " & ws.Index
Exit Sub
End If
Next
End If
' check not existing in list
Dim wb As Workbook, n As Long, lastrow As Long, v
Set wb = ThisWorkbook
With wb.Sheets("Projects")
lastrow = .Cells(.Rows.Count, "D").End(xlUp).Row
v = Application.Match(NewName, .Range("D1:D" & lastrow), 0)
' not existing add to list
If IsError(v) Then
.Cells(lastrow + 1, "D") = NewName
.Cells(lastrow + 1, "E") = Now
Else
MsgBox "Existing Name '" & NewName & "'", vbCritical, "Row " & v
Exit Sub
End If
End With
' create sheet
n = wb.Sheets.Count
wb.Sheets("Template").Copy after:=wb.Sheets(n)
wb.Sheets(n + 1).Name = NewName
MsgBox NewName & " added as Sheet " & n + 1, vbInformation
End Sub

Why are deleted rows reappearing in an excel table when the filter in removed in VBA?

The VBA code I have has worked perfectly on two other machines and with several other worksheets without the data reappearing. I've created a macro that takes a master spreadsheet and creates a new spreadsheet for each school listed in the table. I just got a new laptop and installed Excel 365 on it. I copied the VBA code to the new machine, but when I ran it, each new worksheet still contained the data for all the schools, not just the school for that particular file. I stepped through the code, and the schools did delete, but when it got to the part where the filter was removed from the table ws.ListObjects("Data").AutoFilter.ShowAllData, all the deleted rows reappeared. I'm stumped on why this is happening - It didn't happen on the other two machines and other iterations of the file that I've used this macro on. I don't know if it's an Excel setting or a setting on this particular master file. The other two machines - one used Excel 365, and the other Excel 2016. The data is not part of PowerPivot and is not a PowerQuery, so the data only lives in the table in the worksheet.
Here is the macro:
Dim i As Integer, wb As Workbook, schools() As Variant, schools_to_delete() As Variant
Dim ws As Worksheet, rng As Range, dt As String
schools = SchoolsInList()
dt = MonthName(Month(Now)) & " " & Year(Now)
Set wb = ActiveWorkbook
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Application.DisplayAlerts = False
For i = 1 To UBound(schools)
wb.SaveCopyAs ("Galileo " & dt & " " & schools(i) & ".xlsx")
Workbooks.Open ("Galileo " & dt & " " & schools(i) & ".xlsx")
Workbooks("Galileo " & dt & " " & schools(i) & ".xlsx").Activate
Set ws = Sheets("Data")
ws.Activate
schools_to_delete = schools
schools_to_delete(i) = "x"
Set rng = ws.ListObjects("Data").DataBodyRange
With ws
.AutoFilterMode = False
ws.ListObjects("Data").Range.AutoFilter Field:=18, Criteria1:= _
Array(schools_to_delete), Operator:=xlFilterValues
ws.Range(rng.Address).SpecialCells(xlCellTypeVisible).Delete
.AutoFilterMode = False
ws.ListObjects("Data").AutoFilter.ShowAllData
End With
ActiveWorkbook.RefreshAll
Call SelectA1
ActiveWorkbook.Save
ActiveWorkbook.Close
Next i
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
Application.DisplayAlerts = True
End Sub
Function SchoolsInList() As Variant
Dim schools() As String
Dim C As Collection
Dim r As Range
Dim i As Long
Dim last_row As Long
last_row = Cells(Rows.Count, 1).End(xlUp).Row
Set C = New Collection
On Error Resume Next
For Each r In Worksheets("Data").Range("R2:R" & last_row).Cells
C.Add r.Value, CStr(r.Value)
Next
On Error GoTo 0
ReDim A(1 To C.Count)
For i = 1 To C.Count
A(i) = C.Item(i)
Next i
SchoolsInList = A
End Function
Sub SelectA1()
Dim i As Long
For i = 1 To ActiveWorkbook.Sheets.Count
Sheets(i).Activate
ActiveWindow.ScrollColumn = 1
ActiveWindow.ScrollRow = 1
Range("A1").Select
Next i
ActiveWorkbook.Worksheets(2).Activate
End Sub
I found the problem - the .AutoFilterMode = False didn't actually clear the filters that had already been placed on the table in question. The visible data WAS deleted, but the data that was filtered before the macro was run remained, and when the ws.ListObjects("Data").AutoFilter.ShowAllData ran, it cleared the previous filter, showing the rows that had been filtered before. I added the .ShowAllData code to the beginning of the With statement to avoid the same problem at a future date.

Populate a ComboBox value in a loop?

Hi I am trying to run some code that assigns a combobox a value from a single cell in a range of cells and then executes some formulas on my worksheet and then finally prints a pdf of the output sheet. Everything seems to be working ok, except that the final pdf does not display the value I am running in the combobox (although the sheet calculations have been applied). It may be that my loop executes faster than my combobox can display the value. I'm not really sure. Below is my code:
Application.ScreenUpdating = False
Dim i As Long
Dim ws As Worksheet
Dim FileName As String
Set ws = Sheets("Multi")
Set wsEE = Sheets("Employee")
FileName = ws.Range("B2")
LastRow = ws.Range("A" & Rows.Count).End(xlUp).Row
For i = 7 To LastRow
wsEE.ComboBox4.Value = ws.Range("A" & i)
wsEE.Activate
Application.Calculate
ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, FileName:=ws.Range("B2") & "TCC Analysis - " & ws.Range("A" & i) & ".pdf", _
Quality:=xlQualityStandard, IncludeDocProperties:=True, IgnorePrintAreas:=False
Next i
ws.Activate
Application.ScreenUpdating = True
I also have some code that runs on combobox change. I'm not sure if this could also be part of my problem. Here is that code:
Private Sub ComboBox4_Change()
Sheets("Employee").Range("AZ1") = ComboBox4.Value
Application.Calculate
Application.DisplayAlerts = False
Dim ws As Worksheet
Set ws = Worksheets("Employee")
If Me.ComboBox4 <> -1 Then
ws.Range("C72").Value = ws.Range("C16").Value
ws.Range("C73").Value = ws.Range("C19").Value
End If
Application.Calculate
Application.DisplayAlerts = True
End Sub
Has anyone experienced this problem before? Does anyone have a solution they can provide? Thank you!

Sheet Selection issue with InputBox

I have an Excel VBA file with the following code. My issue is that the InputBox doesn't work correctly. There are 10 sheets. The first sheet is called "Menu". Other sheets as Sheet 2 - 10. Sheet 3,4 & 5 applied VeryHidden. Please help me to rectify it.
Private Sub CommandButton1_Click()
Dim Sh As Worksheet
For Each Sh In ThisWorkbook.Worksheets
If Sh.Name <> "Menu" Then
Sheet3.Visible = xlSheetVeryHidden
Sheet4.Visible = xlSheetVeryHidden
Sheet5.Visible = xlSheetVeryHidden
End If
Next Sh
Dim myList As String
Dim i As Integer
Dim mySht
i = 1
For Each oSheet In ActiveWorkbook.Sheets
If oSheet.Visible <> xlSheetVeryHidden Then
myList = myList & i & " - " & oSheet.Name & " " & vbCr
i = i + 1
End If
Next oSheet
mySht = InputBox("Select Sheet to go to." & vbCr & myList)
ActiveWorkbook.Sheets(CInt(mySht)).Select
End Sub
Like I said in my comment above; The problem is Sheets(CInt(mySht)).
Problem
When you specify a number, say 3, then the code Sheets(CInt(mySht)) becomes Sheets(3). But this is not what you want. You want the name after that number as you are concatenating that number with " - " and then with the sheet name. Sheets(3) actually may be referring to the hidden sheet and not the 3rd Visible sheet and hence you are getting the error.
Option
Instead of using myList, use an array.
Split the array after the user makes a choice and then go to that sheet
Solution
Is this what you are trying?
Private Sub CommandButton1_Click()
Dim Sh As Worksheet
Dim ShName As String
Dim i As Integer
Dim mySht, MyAr
For Each Sh In ThisWorkbook.Worksheets
Sh.Visible = xlSheetVisible
Next Sh
Sheet3.Visible = xlSheetVeryHidden
Sheet4.Visible = xlSheetVeryHidden
Sheet5.Visible = xlSheetVeryHidden
For Each Sh In ThisWorkbook.Worksheets
If Sh.Visible = xlSheetVeryHidden Then i = i + 1
Next Sh
ReDim MyAr(1 To ThisWorkbook.Sheets.Count - i)
i = 1
'~~> Store the names of all visible sheets in the array
For Each Sh In ActiveWorkbook.Sheets
If Sh.Visible = xlSheetVisible Then
MyAr(i) = i & " - " & Sh.Name
i = i + 1
End If
Next Sh
'~~> Get user input
mySht = InputBox("Select Sheet to go to." & vbCr & Join(MyAr, vbNewLine))
If IsNumeric(mySht) Then
'~~> Get the actual sheet name using split as
'~~> we had actually appended " - " to it earlier
ShName = Trim(Split(MyAr(mySht), " - ")(1))
'~~> Activate the sheet
ThisWorkbook.Sheets(ShName).Activate
End If
End Sub

PasteSpecial method of Range class failed when I added password protection

The following macro works fine without the 1st and 3rd lines emphasised (i.e. password protection). When I add the code the macro works the first time but if I open the file again, it returns a run time error 'pastespecial method of range class failed' at the line second line emphasised. The purpose of the macro is to open a purchase order template, increment the purchase order number by one, complete a second log file with date, purchase order number and user name and re-save the purchase order template under a different file name:
Private Sub Workbook_Open()
If ThisWorkbook.ReadOnly Then
MsgBox "Please use dropdown arrow next to filename within SharePoint and select 'Edit in Microsoft Office Excel' instead."
ThisWorkbook.Close
End If
Range("L14") = Range("L14") + 1
ActiveWorkbook.Save
Range("L14").Copy
Workbooks.Open Filename:="\\ehfnp01\users\gminter\My Documents\PO Log Elite\PO Log Elite.xls"
Workbooks("PO Log Elite.xls").Activate
Dim lst As Long
With ActiveWorkbook.Sheets("Sheet1")
*.Unprotect Password:="2"*
lst = .Range("B" & Rows.Count).End(xlUp).Row + 1
**.Range("B" & lst).PasteSpecial xlPasteValuesAndNumberFormats**
End With
With ActiveWorkbook.Sheets("Sheet1")
lst = .Range("A" & Rows.Count).End(xlUp).Row + 1
.Range("A" & lst) = Now
End With
With ActiveWorkbook.Sheets("Sheet1")
lst = .Range("C" & Rows.Count).End(xlUp).Row + 1
.Range("C" & lst).Value = Environ("Username")
*.Protect Password:="2"*
End With
ActiveWorkbook.Save
ActiveWorkbook.Close
ThisFile = Application.DefaultFilePath & "\" & Range("G14").Value & Range("L14").Text
ActiveWorkbook.SaveAs Filename:=ThisFile
Range("L15") = Now
Range("E20").Value = Environ("Username")
ScreenUpdating = False
Set Rng = Intersect(ActiveSheet.UsedRange, Range("e20"))
For Each C In Rng
C.Value = StrConv(C.Value, vbUpperCase)
Next
ScreenUpdating = True
Cells.Locked = False
Range("G14:N15,E20:N20").Locked = True
ActiveSheet.Protect Password:="1"
Dim x As Integer
On Error Resume Next
With ActiveWorkbook.VBProject
For x = .VBComponents.Count To 1 Step -1
.VBComponents.Remove .VBComponents(x)
Next x
For x = .VBComponents.Count To 1 Step -1
.VBComponents(x).CodeModule.DeleteLines _
1, .VBComponents(x).CodeModule.CountOfLines
Next x
End With
On Error GoTo 0
End Sub
Any help would be greatly appreciated as I can't find any similar examples of this.
What happens when you explicitly declare your Objects/Variables and then work with them? That ways you do the copy just before you paste. This will ensure that the clipboard doesn't get cleared for any reason which Excel is unfortunately famous for...
Private Sub Workbook_Open()
Dim rng As Range
Dim newWb As Workbook, wb As Workbook
Dim lst As Long
If ThisWorkbook.ReadOnly Then
MsgBox "Please use dropdown arrow next to filename within SharePoint and select 'Edit in Microsoft Office Excel' instead."
ThisWorkbook.Close
Exit Sub '<~~ ?
End If
Set rng = ThisWorkbook.Sheets("Sheet1").Range("L14")
rng.Value = rng.Value + 1
ThisWorkbook.Save
Set newWb = Workbooks.Open(Filename:="\\ehfnp01\users\gminter\My Documents\PO Log Elite\PO Log Elite.xls")
Set wb = Workbooks("PO Log Elite.xls")
With wb.Sheets("Sheet1")
.Unprotect Password:="2"
lst = .Range("B" & .Rows.Count).End(xlUp).Row + 1
rng.Copy '<~~ Do the copy here
.Range("B" & lst).PasteSpecial xlPasteValuesAndNumberFormats
End With
'
'~~> Rest of the code
'
End Sub

Resources