Copy worksheet with specified name to another workbook - excel

This macro copies Excel worksheets that have a numeric name to another Excel workbook.
For example only worksheets that are titled with 6 digits. For Example "140655".
I want to also copy over the worksheets that have a standard English name such as "Budget".
Const CalcDelay = 0.00000578704
Dim CopyRange As String
Dim PasteRange As String
Dim ScanFileOpen As Byte
Dim ScanCount As Byte
Dim ScanSaveSpec As String
Dim ScanSaveFile As String
Dim ReturnWindow As String
Dim ReportFile As String
Dim ExcelVersion As String
Sub OpenReportFile()
ReturnWindow = [ProcessWinSpec].Value
If [ReportFileFlag].Value = True Then
Application.ScreenUpdating = False
Workbooks.Open Filename:=[ReportFileSpec].Value
Windows(ReturnWindow).Activate
Application.ScreenUpdating = True
Else
MsgBox ("Error: File not found")
End If
End Sub
Sub DoScan()
Dim Work As Variant
Dim X As Interger
ReturnWindow = [ProcessWinSpec].Value
ReportFile = [ReportFileName].Value
ExcelVersion = IIf([FileNameExt].Value = ".xls", 2003, 2013)
For Each Work In [ScanFlags]
ScanFileOpen = 0
ScanCount = 0
If Work.Value = 1 Then
[ScanName].Value = Work.Offset(0, 1).Value
[ScanCalcRange].Calculate
ScanSaveFile = [ScanFile].Value
ScanSaveSpec = [ScanSpec].Value
For X = Work.Offset(0, 2).Value To 1 Step -1
ScanTabName = Work.Offset(0, X + 2).Value
[ScanTab].Value = ScanTabName
[ScanCalcRange].Calculate
If [ReadFlag].Value = 1 Then DoCopyTab
Next
End If
If ScanFileOpen = 1 Then
ActiveWorkbook.Save
ActiveWindow.Close
End If
Next
End Sub

With regards to your question on how to excecute a macro if files have a certain name, probably the best approach would be to create an array of words, and then loop through them seeking a match. See example with your code:
Sub OpenReportFile()
Const yourWords = "budget,actual,accept" '<--- fill these in separated by comman
ReturnWindow = [ProcessWinSpec].Value
Dim foundMatch As Boolean
If [ReportFileFlag].Value = True Then
foundMatch = True
Else
Dim wordArray() As String, i As Long
wordArray = Split(yourWords, ",")
'loopS through words
For i = LBound(wordArray) To UBound(wordArray)
If UCase(wordArray(i)) = UCase([ReportFileFlag].Value) Then
foundMatch = True
Exit For 'exits loop after match
End If
Next i
End If
If foundMatch Then
Application.ScreenUpdating = False
Workbooks.Open Filename:=[ReportFileSpec].Value
Windows(ReturnWindow).Activate
Application.ScreenUpdating = True
Else
MsgBox ("Error: File not found")
End If
End Sub
As you can see in the comments, your question isn't receiving the most favorable feedback as far as clarity. If this doesn't work, you may want to consider eleting your question and reposting after more carefully reviewing How to ask a question

Related

Create a new sheet from a template sheet

i have created a vba script which helps me to create new sheets in my workbook every time i enter a new column. What i want to change is to create a new sheet but copying a template sheet for that new sheet.
I basically create a "home sheet" where i will divide the curriculum into lessons, then i want the script to run and create a lesson plan sheet for each lesson. Please can someone help me with this?
Sub add()
Call CreateWorksheets(Sheets("Lesson List").Range("B2:XFD2"))
End Sub
Sub CreateWorksheets(Names_Of_Sheets As Range)
Dim No_Of_Sheets_to_be_Added As Integer
Dim Sheet_Name As String
Dim i As Integer
No_Of_Sheets_to_be_Added = Names_Of_Sheets.Columns.Count
For i = 1 To No_Of_Sheets_to_be_Added
Sheet_Name = Names_Of_Sheets.Cells(1, i).Value
If (Sheet_Exists(Sheet_Name) = False) And (Sheet_Name <> "") Then
Worksheets.add(After:=ActiveWorkbook.Worksheets(ActiveWorkbook.Worksheets.Count)).Name = Sheet_Name
End If
Next i
End Sub
Function Sheet_Exists(WorkSheet_Name As String) As Boolean
Dim Work_sheet As Worksheet
Sheet_Exists = False
For Each Work_sheet In ThisWorkbook.Worksheets
If Work_sheet.Name = WorkSheet_Name Then
Sheet_Exists = True
End If
Next
End Function
My edited code with me trying to use the copy function:
Sub add()
Call CreateWorksheets(Sheets("Lesson List").Range("B2:XFD2"))
End Sub
Sub CreateWorksheets(Names_Of_Sheets As Range)
Dim No_Of_Sheets_to_be_Added As Integer
Dim Sheet_Name As String
Dim i As Integer
'determine the number of sheets to create
No_Of_Sheets_to_be_Added = Names_Of_Sheets.Columns.Count
For i = 1 To No_Of_Sheets_to_be_Added
'lable each sheet
Sheet_Name = Names_Of_Sheets.Cells(1, i).Value
If (Sheet_Exists(Sheet_Name) = False) And (Sheet_Name <> "") Then
Worksheets("Lesson Plan Template").Copy After:=ActiveWorkbook.Worksheets(ActiveWorkbook.Worksheets.Count).Name = Sheet_Name
End If
Next i
End Sub
Function Sheet_Exists(WorkSheet_Name As String) As Boolean
Dim Work_sheet As Worksheet
Sheet_Exists = False
For Each Work_sheet In ThisWorkbook.Worksheets
If Work_sheet.Name = WorkSheet_Name Then
Sheet_Exists = True
End If
Next
End Function
Although i have not tidy up the error handling and my function as suggested i did follow the suggest of adding additional steps which gave me the desirable results:
Sub Add_New_Lesson()
Call Copy_Lesson_Template(Sheets("Lesson List").Range("B2:XFD2"))
End Sub
Sub Copy_Lesson_Template(Names_Of_Sheets As Range)
Dim No_Of_Sheets_to_be_Added As Integer
Dim Sheet_Name As String
Dim i As Integer
No_Of_Sheets_to_be_Added = Names_Of_Sheets.Columns.Count
For i = 1 To No_Of_Sheets_to_be_Added
Sheet_Name = Names_Of_Sheets.Cells(1, i).Value
If (Sheet_Exists(Sheet_Name) = False) And (Sheet_Name <> "") Then
Worksheets("Lesson Template").Copy After:=Sheets(Sheets.Count)
ActiveSheet.Name = (Sheet_Name)
End If
Next i
End Sub
Function Sheet_Exists(WorkSheet_Name As String) As Boolean
Dim Work_sheet As Worksheet
Sheet_Exists = False
For Each Work_sheet In ThisWorkbook.Worksheets
If Work_sheet.Name = WorkSheet_Name Then
Sheet_Exists = True
End If
Next
End Function
Check out the following solution including some proper error handling.
Sub CreateWorksheets(Names_Of_Sheets As Range)
'determine the number of sheets to create
Dim No_Of_Sheets_to_be_Added As Long
With Names_Of_Sheets
No_Of_Sheets_to_be_Added = .Resize(ColumnSize:=1).Offset(ColumnOffset:=.Columns.Count - .Column + 1).End(xlToLeft).Column - .Column + 1
End With
Dim i As Long
For i = 1 To No_Of_Sheets_to_be_Added
Dim Sheet_Name As String
Sheet_Name = Names_Of_Sheets.Cells(1, i).Value
If Not Sheet_Exists(Sheet_Name) And Sheet_Name <> vbNullString Then
Dim TemplateCopy As Worksheet
Set TemplateCopy = Nothing 'initialize (needed because we are within a loop)
On Error Goto COPY_TEMPLATE_ERROR 'if error occurs throw message
Set TemplateCopy = Worksheets("Lesson Plan Template").Copy(After:=ActiveWorkbook.Worksheets(ActiveWorkbook.Worksheets.Count))
On Error Goto 0 're-enable error handling!
If Not TemplateCopy Is Nothing Then 'check if the template copy exists
On Error Goto RENAME_COPY_ERROR
TemplateCopy.Name = Sheet_Name
On Error Goto 0 're-enable error handling!
End If
End If
Next i
Exit Sub
COPY_TEMPLATE_ERROR:
MsgBox "Template worksheet could not be copied."
Resume
RENAME_COPY_ERROR:
MsgBox "Template could not be renamed to '" & Sheet_Name & "'!"
'remove the template copy that could not be renamed (or you will have orphaned template copys)
Application.DisplayAlerts = False
TemplateCopy.Delete
Application.DisplayAlerts = True
Resume
End Sub
Make sure ActiveWorkbook is what you actually mean it to be:
ActiveWorkbook is the workbook that has focus (is on top of the other windows) while the code runs. This can easily change by a single mouse click.
ThisWorkbook is the workbook this VBA code is written in. It will never change. Use this over ActiveWorkbook when ever possible. This is much more reliable.
Note that if you work with multiple workbooks, every Worksheets or Sheets object needs to start with either ActiveWorkbook.Worksheets, ThisWorkbook.Worksheets or Workbooks("your-workbook-name.xlsm").Worksheets otherwise it is not clear for VBA which one of these you actually mean and it makes a guess (and it might guess wrong).
Finally the name of your function Sheet_Exists is a bit missleading because it only works for Worksheets as it is coded right now. Make sure you know the difference:
Sheets() contains all type of sheets: Worksheet, chart sheet, etc.
Worksheets() only contains sheets of type worksheet.
So your function should be called Worksheet_Exists
Function Worksheet_Exists(WorkSheet_Name As String) As Boolean
Dim Work_sheet As Worksheet
For Each Work_sheet In ThisWorkbook.Worksheets
If Work_sheet.Name = WorkSheet_Name Then
Worksheet_Exists = True
Exit Function 'if we found the name we don't need to check further worksheets
End If
Next Work_sheet
End Function
Or it needs to be changed to work for all type of sheets:
Function Sheet_Exists(Sheet_Name As String) As Boolean
Dim Sheet As Object
For Each Sheet In ThisWorkbook.Sheets
If Sheet.Name = Sheet_Name Then
Sheet_Exists = True
Exit Function 'if we found the name we don't need to check further sheets
End If
Next Sheet
End Function

VBA: copy sheet mantain defined name

I have an excel sheet with defined names I would like to copy it with VBA by copying also the defined names. How can I do?
My current macro to copy the sheet:
Sub myMacro()
Const BASE_NAME As String = "MySheet"
Dim sheet_name As String
Dim i As Integer
Dim num_text As String
Dim new_num As Integer
Dim max_num As Integer
Dim new_sheet As Worksheet
' Find the largest number in a sheet name after the
' base name.
max_num = 0
For i = 1 To Sheets.Count
sheet_name = Sheets(i).Name
If Left$(sheet_name, Len(BASE_NAME)) = BASE_NAME _
Then
num_text = Mid$(sheet_name, Len(BASE_NAME) + 1)
new_num = Val(num_text)
If new_num > max_num Then max_num = new_num
End If
Next i
' Make a new sheet with a new number.
Set new_sheet = Sheets.Add(after:=Sheets(Sheets.Count))
new_sheet.Name = BASE_NAME & Format$(max_num + 1)
new_sheet.Select
Sheets("MySheet_template").Range("A1:DQ1109").Copy
Destination:=Sheets(new_sheet.Name).Range("A1")
End Sub
Try this - a slightly different approach
Sub myMacro()
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Dim sh As Shape, strtSh As Worksheet
Set strtSh = ActiveSheet
Sheets("MySheet_template").Copy after:=Sheets(Sheets.Count)
ActiveSheet.Name = "MySheet" & Sheets.Count - 1
For Each sh In ActiveSheet.Shapes
sh.Delete
Next sh
strtSh.Select
Application.ScreenUpdating = True
Application.DisplayAlerts = True
End Sub

VBA Code to Create Sheets based on the values in column A

I am looking for a code to create sheets with the name in column A. I have used this code but it is not fulfulling my requirement. The code is ;
Private Sub CommandButton1_Click()
Dim sheetCount As Integer
Dim sheetName As String
Dim workbookCount As Integer
With ActiveWorkbook
sheetCount = Sheets(1).Range("A2").End(xlDown).Row
For i = 2 To sheetCount Step 1
sheetName = .Sheets(1).Range("A" & i).Value
workbookCount = .Worksheets.Count
.Sheets.Add After:=Sheets(workbookCount)
.Sheets(i).Name = sheetName
'.Sheets(i).Range("A" & i, "F" & i).Value = .Sheets("sample").Range("A" & i, "F" & i).Value
Next
End With
Worksheets(1).Activate
End Sub
Upon running this code in first go, it creates sheets with the text present in column A. But the problem is when i entered new text in that column, it makes previous sheets as well. I am looking for a code which only create the sheets with the new text being entered in the column and donot make sheets which are already made. Kindly help me out on this as i tried too much but didnt find any code.
Thanks
This works for me, and is tested: Note, if you try to use a name like "History" that is reserved you will get an error. I am not aware of all the reserved names.
Private Sub CommandButton1_Click()
Dim lastRow As Long
Dim sheetName As String
Dim workbookCount As Long
Dim ws As Worksheet
Dim match As Boolean
lastRow = Sheets("Sheet1").Range("A2").End(xlDown).Row
For i = 2 To lastRow
match = False
sheetName = Sheets("Sheet1").Cells(i, 1).Text
For Each ws In ActiveWorkbook.Worksheets
If ws.Name = sheetName Then
match = True
End If
Next
If match = False Then
Worksheets.Add(After:=Worksheets(Worksheets.Count)).Name = sheetName
End If
Next i
End Sub
Edit: Added Screen Shots
You can try thi function:
Function SheetExists(SheetName As String) As Boolean
Dim Test As Boolean
On Error Resume Next
Test = Sheets(SheetName).Range("A1").Select
If Test Then
SheetExists = True
Else
SheetExists = False
End If
End Function
Using the function this way:
Sub test()
If SheetExists("MySheet") Then
MsgBox "Sheet exists"
Else
MsgBox "Sheet is missing"
End If
End Sub
I usually have these two helper functions in my workbooks / personal workbook
Option Explicit
Function getSheetWithDefault(name As String, Optional wb As Excel.Workbook) As Excel.Worksheet
If wb Is Nothing Then
Set wb = ThisWorkbook
End If
If Not sheetExists(name, wb) Then
wb.Worksheets.Add(After:=wb.Worksheets(wb.Worksheets.Count)).name = name
End If
Set getSheetWithDefault = wb.Sheets(name)
End Function
Function sheetExists(name As String, Optional wb As Excel.Workbook) As Boolean
Dim sheet As Excel.Worksheet
If wb Is Nothing Then
Set wb = ThisWorkbook
End If
sheetExists = False
For Each sheet In wb.Worksheets
If sheet.name = name Then
sheetExists = True
Exit Function
End If
Next sheet
End Function
To create the worksheets you just iterate over the sheet names and use the getSheetwithDefault function
The following code demonstrate this:
sub createSheets()
dim cursor as Range: set cursor = Sheets("Sheet1").Range("A2")
while not isEmpty(cursor)
getSheetWithDefault(name:=cursor.value)
set cursor = cursor.offset(RowOffset:=1)
wend
end

Need some advice on how to stream line ACCESS/EXCEL VBA

I wrote this Access/VBA program. It works but only when I am not running other applications or few users are in the database. I need some ideas on streamlining the code. So it is not so system intensive. The program basically allows a user to pick a folder and then combines all worksheets in that folder in one excel document. My current idea is just to tell users to close all excel files when trying to run the program. Please Help:
Sub Excel_open()
Dim myXL As Excel.Application
Dim myXLS As Excel.Workbook
Const errExcelNotRunning = 429
On Error GoTo HandleIt
Set myXL = GetObject(, "Excel.application")
myXL.Visible = True
Set myXLS = myXL.Workbooks.Add
Call CombineWorkbooks(myXL)
HandleIt:
If Err.Number = errExcelNotRunning Then
Set myXL = CreateObject("Excel.Application")
Err.Clear
Resume Next
End If
End Sub
Sub CombineWorkbooks(myXL)
'Macro that combines the files into one folder
myXL.AskToUpdateLinks = False
myXL.DisplayAlerts = False
Dim CurFile As String, dirloc As String, strNamesheet As String
Dim DestWB As Workbook
Dim ws As Object ' allows for diffrent sheet types
'Add select the director function
dirloc = GetFolderName & "\" 'location of files not working want to select the file only
CurFile = Dir(dirloc & "*.xls*")
myXL.ScreenUpdating = False
myXL.EnableEvents = False
Set DestWB = Workbooks.Add(xlWorksheet)
Do While CurFile <> vbNullString
Dim OrigWB As Workbook
Set OrigWB = Workbooks.Open(FileName:=dirloc & CurFile, ReadOnly:=True)
'need to change a name active name is not doing it
CurFile = Left(CurFile, 4) ' This is no longer 29
'CurFile = Left(Left(CurFile, Len(CurFile) - 5), 29)
For Each ws In OrigWB.Sheets
ws.Copy After:=DestWB.Sheets(DestWB.Sheets.Count)
' Use the name to give the sheet a name
strNamesheet = Left((ws.Name), 25) & ";"
If OrigWB.Sheets.Count > 1 Then
DestWB.Sheets(DestWB.Sheets.Count).Name = strNamesheet & CurFile ' & ws.Index
Else
DestWB.Sheets(DestWB.Sheets.Count).Name = CurFile
End If
Next
OrigWB.Close SaveChanges:=False
CurFile = Dir
Loop
myXL.DisplayAlerts = False
DestWB.Sheets(1).Delete
myXL.DisplayAlerts = True
myXL.ScreenUpdating = True
myXL.EnableEvents = True
Set DestWB = Nothing
Call Delete_empty_Sheets(myXL)
Call Sort_Active_Book
MsgBox "Done"
'Call Xcombine_the_Matching
End Sub
Sub Delete_empty_Sheets(myXL)
'goes through all sheets and deletes
Reset_the_search:
For Each wsElement In Worksheets
If wsElement.Range("A2") = "" And wsElement.Range("B2") = "" Then
myXL.DisplayAlerts = False
wsElement.Delete
GoTo Reset_the_search
myXL.DisplayAlerts = True
End If
Next wsElement
End Sub
Sub Xcombine_the_Matching()
'I think I can make the order work
'change and transpose the array
Dim varStart As Variant
Dim wsCompare As Worksheet
Dim strMatch As String
'Dim varCompare As Variant
Dim strVareince As String
Dim strCurrentName As String
'you need to build a loop to solve this problem
For Each wsCompare In Worksheets
strVareince = Add_Array(Application.Transpose(wsCompare.Range("A1:Z1")))
For Each wsNompare In Worksheets
If wsNompare.Name <> strCurrentName Then
If strVareince = Add_Array(Application.Transpose(wsNompare.Range("A1:Z1"))) Then
MsgBox ("Matched with worksheet " & wsNompare.Name)
End If
End If
Next
Next
End Sub
Function array_to_string(x) As String
For Z = 1 To 26
array_to_string = array_to_string & x(Z, 1) & ";"
Next Z
End Function
Function GetFolderName(Optional OpenAt As String) As String
'Allows you to select the folder director that you want to combine
Dim lCount As Long
GetFolderName = vbNullString
With Application.FileDialog(msoFileDialogFolderPicker)
.InitialFileName = OpenAt
.Show
For lCount = 1 To .SelectedItems.Count
GetFolderName = .SelectedItems(lCount)
Next lCount
End With
End Function
Function Add_Array(x) As String
'turns an excel document
For d = 1 To UBound(x)
Add_Array = Add_Array & x(d, 1)
Next d
End Function
Sub Read_data()
'this the
End Sub
Sub Sort_Active_Book()
Dim i As Integer
Dim j As Integer
Dim iAnswer As VbMsgBoxResult
'
' Prompt the user as which direction they wish to
' sort the worksheets.
'
iAnswer = MsgBox("Sort Sheets in Ascending Order?" & Chr(10) _
& "Clicking No will sort in Descending Order", _
vbYesNoCancel + vbQuestion + vbDefaultButton1, "Sort Worksheets")
For i = 1 To Sheets.Count
For j = 1 To Sheets.Count - 1
'
' If the answer is Yes, then sort in ascending order.
'
If iAnswer = vbYes Then
If UCase$(Sheets(j).Name) > UCase$(Sheets(j + 1).Name) Then
Sheets(j).Move After:=Sheets(j + 1)
End If
'
' If the answer is No, then sort in descending order.
'
ElseIf iAnswer = vbNo Then
If UCase$(Sheets(j).Name) < UCase$(Sheets(j + 1).Name) Then
Sheets(j).Move After:=Sheets(j + 1)
End If
End If
Next j
Next i
End Sub
You are passing your Excel Application object into your subroutines, but not using it fully, neither are you explicitly referencing the libraries:
Sub CombineWorkbooks(myXL)
Dim DestWB As Excel.Workbook ' <<<
Set DestWB = myXL.Workbooks.Add(xlWorksheet) ' <<<
End Sub
Run through your code and fix all of these first, then test & supply more feedback on what the precise symptoms of the problems are.

How to check the cell value of other workbook is empty or not in excel vba

Dim ConsolidateSheetObj As Workbook
Dim str As String
Dim keycount,row As Interger
Set ConsolidateSheetObj = Workbooks.open("filePath")
Set str = ConsolidateSheetObj.Sheets(3).Cells(row, 17 + keycount).Value
If str.IsEmpty() Then
. . .
...
End If
Coercing to a string and checking its length is a poor way to do this. Additionally, your using Set str is syntatically invalid: Set is only used for object types.
A better way is:
Dim v as Variant
v = ConsolidateSheetObj.Sheets(3).Cells(row, 17 + keycount).Value
If VarType(v) = vbEmpty Then
'this is an empty range
End If
Sub checkEmpty()
'Used variables
Dim filePath As String
Dim sheet, row, keycount As Integer
Dim cellEmpty As Boolean
'Disable Screen updates
Application.ScreenUpdating = False
filePath = "C:\Your_file.xlsx"
sheet = 3
row = 3
keycount = 2
cellEmpty = False
'Open other workbook
Workbooks.Open Filename:= _
filePath
'Check if cell is empty
If isEmpty(Sheets(sheet).Cells(row, 17 + keycount)) Then
cellEmpty = True
End If
'Close other workbook
Application.DisplayAlerts = False
ActiveWorkbook.Close SaveChanges:=No
If cellEmpty Then
MsgBox ("Cell is Empty!")
'...Your Code here!
End If
'Enable Screen updates
Application.ScreenUpdating = True
End Sub

Resources