Create another sheet if only 1 exists and use it VBA - vba

I had a working program that uses Sheet1 and Sheet2 in the code. However, now I realized that if I remove Sheet2 and create new sheet that sheet number is no longer being used. What I actually need to do is to create another sheet if only 1 exists and then use that in my code. However, my trials have not worked so far. I used to have code like this to define variables:
Dim datasheet As Worksheet
Dim reportsheet As Worksheet
Set datasheet = Sheet1
set reportsheet = Sheet2
Of course this doesnt work anymore since I deleted Sheet2 and excel remembers your past mistakes. I tried to circumvent this by doing following:
Set datasheet = Sheet1
'Create reportsheet if it doesnt exist
Dim ws As Worksheet
CreateSheetIf = False
Set ws = Nothing
On Error Resume Next
Set ws = ActiveWorkbook.Worksheets("reportdata")
On Error GoTo 0
If ws Is Nothing Then
CreateSheetIf = True
Worksheets.Add.Name = "reportdata"
End If
Set reportsheet = ws
Unfortunately, here I run into an error in my later code which tries to empty the reportsheet:
reportsheet.Range("A1:H200").ClearContents
What I would like to have is to create a new sheet in addition to sheet1 if there is none. This sheet should be located after the Sheet1 in the sheet listing. My further code would utilize this as the reportsheet (I move data from Sheet1 to Sheet2). Someone has any tips on what I am doing wrong and how to do it better?

You do not need to rename the sheet, or have it called Sheet1 and Sheet2. You could access it dynamically relative to their index. For example:
Set datasheet = Worksheets(1) ' The first sheet in the workbook
set reportsheet = Worksheets(2) ' The second sheet in the workbook

I see lack of focus there, you first try to refer to worksheets by Object name (Sheet1, Sheet2) and then by Tab name ("reportdata").
Set ws = ActiveWorkbook.Worksheets("reportdata") with error supression is a good way to handle it, although you try to do the following after:
Set reportsheet = ws
The problem is that if you go through code, you will notice that at this stage Object ws is Nothing if there was no "reportdata" worksheet prior to running this code.
Use:
Set reportsheet = ActiveWorkbook.Worksheets("reportdata")

You can use the worksheet index number instead of the codename.
Option Explicit
Sub repBuild()
Dim datasheet As Worksheet
Dim reportsheet As Worksheet
Set datasheet = Sheet1
On Error GoTo createSecondWs
Set reportsheet = Worksheets(2)
On Error GoTo 0
'build report here with reportsheet
Exit Sub
createSecondWs:
With Worksheets.Add(after:=Worksheets(Worksheets.Count))
.Name = "Report Sheet"
'perform other basic report template operations here before returning
End With
Resume
End Sub
This uses error control to create a second worksheet if only one exists.

Related

VBA Copy Worksheet to a Different Open Workbook

I keep getting an Out of Range error when trying to copy a sheet from on workbook to another. The original spreadsheet (Master_Data.xlsm) is what is running the vba script. The scripts opens another spreadsheet, manipulates it, then copies the final sheet to be pasted in the Master_Data.xlsm Workbook.
Sub Result_Scrapper()
Dim wb As Workbook, ws As Worksheet, wbFile As Object
Dim masterBook As Workbook
Dim wsa As Worksheet
Dim year As Integer
Set fso = CreateObject("Scripting.FileSystemObject")
Set fldr = fso.GetFolder("C:\Users\Output_Spreadsheets\")
Set masterBook = Excel.Workbooks("Master_Data.xlsm")
Application.ScreenUpdating = False
For Each wbFile In fldr.Files
If fso.GetExtensionName(wbFile.Name) = "xlsm" Then
Set wb = Workbooks.Open(wbFile.Path)
'Copy sheet of interest
ActiveSheet.Copy 'Before:=ThisWorkbook.Sheets(“A”) 'tried doing it using before statement but it also caused errors
'paste sheet into masterBook spread--this is where the error comes
masterBook.Sheets(Sheets.Count).Paste
End If
masterBook.Sheets("master").Name = Right([A2], 30)
Next wbFile
There are two issues. First, as someone else commented, you need to fully qualify the count. Second, you'll want to do it on one line; and you could do before, but then you're just pushing out whatever that last sheet is, if you add it after, then the sheets stay in order.
Try:
ActiveSheet.Copy After:=masterBook.Sheets(masterBook.Sheets.Count)

Excel VBA: Counting Data in Column from Another Workbook and Inputting Counter in Master Workbook

I need to create a macro in my CountResults.xlsm (Master Workbook) that solves the following problem. I have a column of data in another worksheet with either YES or NO. I need to come up with a macro that counts the amount of "YES" in the column. The column is located in Sheet2 of the workbook Test01.xlsx. Then take that count and put it in one cell in my CountResults.xlsm file. Like so:
I have a code that displays a count for a column in the same sheet. But this code does not count when there are 'breaks' in the column (empty spaces) like I have in my picture. This is that code:
Private Sub CommandButton1_Click()
MsgBox Range("A1").End(xlDown).Row
Range("A1").End(xlDown).Offset(1, 0).Select
End Sub
I have another code that helps with accessing another workbook and defining values for each workbook and worksheet:
Dim wbSource As Workbook
Dim wbTarget As Workbook
Dim shSource As Worksheet
Dim shTarget As Worksheet
Set wbSource = Workbooks.Open(Filename:="C:\Users\khanr1\Desktop\Test_Excel\Test03.xlsm", ReadOnly:=True)
Set wbTarget = ThisWorkbook
Set shSource = wbSource.Worksheets("Sheet2")
Set shTarget = wbTarget.Worksheets("Sheet1")
Use COUNTIF. It will give you the total even if the range is in another workbook. i.e. =COUNTIF([Book2.xlsx]Sheet2!$D$2:$D$9, "Yes"). Problem with having COUNTIF within your sheet as a formula is that you will need to open the other workbook if you want the count to be update. Below VBA code will perform an update for you. Assign the sub to a button in your CountResults.xlsm workbook
EDIT: Added row count as per OP's requirement
Sub UpdateResults()
Dim oWBWithColumn As Workbook: Set oWBWithColumn = Application.Workbooks.Open("<your Test01.xlsx address here>")
Dim oWS As Worksheet: Set oWS = oWBWithColumn.Worksheets("Sheet2")
Dim intLastRow as Integer: intLastRow = oWS.Cells(Rows.Count, "B").End(xlUp).Row
ThisWorkbook.Worksheets("<name of the sheet in your CountResults.xlsm workbook>").Range("<cell address>").Value = Application.WorksheetFunction.CountIf(oWS.Range("B2:B" & intLastRow), "yes")
oWBWithColumn.Close False
Set oWS = Nothing
Set oWBWithColumn = Nothing
End Sub

Runtime Error 1004 Method "Range" of object "_Worksheet" failed

I am trying to combine numerous sheets into one new sheet. I would really appreciate any comments.
The issue is with the line:
wsSrc.Range("A1", wsSrc.Range("D", lastRow)).Copy Destination:=rngDest
Which causes the error when I try to run it. I have previously been using the code to combine all the sheets into the sheet Summary which is where the button for the macro is created which worked fine.
Sub mcrCombine()
ActiveWorkbook.Sheets.Add.Name = "Combined" 'Create new sheet
'Definitions
Dim wsSrc As Worksheet
Dim wsDest As Worksheet
Dim rngDest As Range
Dim lastRow As Long
Dim destRow As Long
Set wsDest = Worksheets("Combined") 'Destination sheet in same Workbook
Set rngDest = wsDest.Range("B1") 'Destination cell in Combined
Application.DisplayAlerts = False 'suppress prompt worksheet delete
'loop through all sheets
For Each wsSrc In ThisWorkbook.Sheets
If wsSrc.Name <> "Summary" And wsSrc.Name <> "Combined" Then 'all sheets except summary
lastRow = wsSrc.Cells.SpecialCells(xlCellTypeLastCell).Row 'define last row
wsSrc.Range("A1", wsSrc.Range("D", lastRow)).Copy Destination:=rngDest 'copy and paste data in range
Set rngDest = rngDest.Offset(lastRow - 1) 'update destination range
wsSrc.Delete 'delete source file
End If
Next
Application.DisplayAlerts = True 'prompts back on
End Sub
OK, I am not sure that this will get your code to achieve all what it is supposed to do, but since you corrected to issue pointed out by #Jeeped and specified your issue within this line:
wsSrc.Range("A1", wsSrc.Range("D", lastRow)).Copy Destination:=rngDest
The error in this line is because of the comma instead of the ampersand. You should change it into:
wsSrc.Range("A1", "D" & lastRow).Copy Destination:=rngDest
Hope this helps.
I have previously been using the code to combine all the sheets into the sheet Summary which is where the button for the macro is created which worked fine.
That's the clue as to what is occurring. As you cycle through each of the worksheets in the workbook you take care not to process the Summary worksheet; probably because a) it already holds aggregated information from the other worksheets and b) you do not want it deleted with the other worksheets that are processed.
If you have changed the central location to a Combined worksheet you are going to have to include that in the worksheet(s) to skip over. Failure to skip over the Combined worksheet will a) copy its content on top of itself and b) delete the Combined worksheet.
If wsSrc.Name <> "Summary" And wsSrc.Name <> "Combined" Then
If you delete the Combined worksheet, then there is Nothing in the way of a destination.

Copy range to new worksheet fails

VBA newbie having trouble copying a sheet into another with offset.
Copying the entire sheet works but I can't get copy with offset to function the same way.
What am I missing?
source.Copy ThisWorkbook.Sheets(Sheets.Count) 'works
source.Range("A12").Copy Destination:=ThisWorkbook.Sheets(Sheets.Count) 'fails
You were trying to paste a range on a sheet object, but you need to specify the initial range (top left cell) where you want to paste in that sheet! ;)
source.Range("A12").Copy Destination:=ThisWorkbook.Sheets(Sheets.Count).Range("A1")
You could also use "range-transfer" which is far more efficient than copy :
ThisWorkbook.Sheets(Sheets.Count).Range("A1").Value = source.Range("A12").Value
And here is how to create a new sheet and paste from the old one :
Sub test_frostbite()
Dim wB As Workbook, _
WsNEW As Worksheet, _
Source As Worksheet
Set wB = ActiveWorkbook
Set Source = wB.Sheets("SheetName")
Set WsNEW = wB.Sheets.Add
Source.UsedRange.Copy Destination:=WsNEW.Range("A1")
End Sub

excel vba insert column runtime error 1004

this is my first post on StackExchange! I've been using StackExchange for answers, but now i really have a question.
I am trying to add a column in excel using vba. This is procedure is part of a bigger sub function of which I created a new workbook and copy a series of sheets from a different workbook over.
Workbooks.Add
Set TTB = ActiveWorkbook
'add a bunch of sheets here
'sheetName = specific_sheet
Set ttb_sheet = TTB.Sheets(sheetName)
ttb_sheet.Columns("I:I").Insert Shift:=xlToRight
With this i get a runtime error of 1004: 'Insert method of Range class failed'
I tried following a series of questions on StackOverflow...
Select method of Range class failed via VBA
VBA error 1004 - select method of range class failed
It seems like the solution is to select the sheet first, then select the range. I have tried this and there was no luck. Anyone have any insight?
Here's my main sub code..
Sub create_TTB_workbook(TTB_name_)
'create TTB workbook
Dim wsHelper As New WorksheetHelper
Dim final_TTB As Workbook
Dim ttb_sheet As Worksheet
ttb_wb = ActiveWorkbook.name
Workbooks(ttb_wb).Activate
PCB_tab = 0
ST_COMP_tab = 0
For Each WS In Worksheets
If WS.name = "PCB_PIN_REPORT" Then
PCB_tab = 1
End If
If WS.name = "ST_PIN_REPORT" Then
ST_COMP_tab = 1
End If
Next WS
Workbooks.Add
Set TTB = ActiveWorkbook
new_ttb_wb = TTB.name
Debug.Print (new_ttb_wb)
If PCB_tab = 1 Then
wsHelper.copySheet ttb_wb, "PCB_PIN_REPORT", new_ttb_wb, "PCB_PIN_REPORT"
End If
If ST_COMP_tab = 1 Then
wsHelper.copySheet ttb_wb, "ST_PIN_REPORT", new_ttb_wb, "ST_PIN_REPORT"
End If
wsHelper.copySheet ttb_wb, TTB_name_, new_ttb_wb, TTB_name_
' TRIED A BUNCH OF METHODS here...
'Workbooks(ttb_wb).Sheets(TTB_name_).Cells.copy
'Sheets.Add.name = TTB_name_
'ActiveSheet.paste
'Sheets(TTB_name_).Activate
'Columns("I:I").Insert Shift:=xlToRight, CopyOrigin:=xlFormatFromLeftOrAbove
'Worksheets(TTB_name_).Range("I1").EntireColumn.Insert
'Columns("I:I").Select
'Columns("I:I").Insert Shift:=xlToRight
Set ttb_sheet = Sheets(TTB_name_)
ttb_sheet.Columns("I:I").Insert Shift:=xlToRight
Columns("K").copy Destination:=Range("I1")
Range("I6") = "header name"
End Sub
Whenever I run into an issue like this, I always isolate the code to its simplest form. Once I get it working at that level, I add it back in to the full application and can usually figure out what I did wrong.
I've written a simple version of what you are trying to do. Note that I've included a few Debug.Print statements to help me verify what is going on. The debug messages will appear in your Immediate window. Obviously you can also step through the code and examine variables as you go.
To get this to work, create a workbook and save it as DestinationWorkbook.xlsx. Then open another workbook and insert the code below.
Sub InsertColumnInDestinationWorksheet()
Dim sourceWb As Workbook
Dim targetWb As Workbook
Dim sourceWs As Worksheet
Dim targetWs As Worksheet
Set sourceWb = ThisWorkbook
Debug.Print sourceWb.Name
Set targetWb = Workbooks("DestinationWorkbook.xlsx")
Debug.Print targetWb.Name
Set sourceWs = sourceWb.Sheets("Sheet1")
Debug.Print sourceWs.Name
Set targetWs = targetWb.Sheets("Sheet1")
Debug.Print targetWs.Name
targetWs.Range("I1").Value2 = "Moving right along..."
targetWs.Columns("I:I").Insert shift:=xlToRight
End Sub
After running the code, you can examine the target sheet. You should see the text we wrote into column I is now in column J.
This works for me when I change the variable naming to:
Sub testingg()
Dim ttb_sheet As Worksheet
Set ttb_sheet = Sheets(1)
ttb_sheet.Columns("I:I").Insert Shift:=xlToRight
End Sub
So I presume there's an issue with the way you reference the workbook when setting ttb_sheet on line 3. Note that you add a workbook but you aren't actually 'activating' it necessarily. And are you sure the 'Sheetname' actually exists in the TTB workbook?