In my excel file I have a worksheet for every person. This worksheet is copied according a template sheet after entering data.
Now for the next part I would like to add data to a specific range on the sheet of that person.
Let's start with a simple date stamp to Range E4:E53 for the specified sheet. I'm using a combobox so you can select someone from the list and this is where i'm struggling;
After selecting someone from the list, my code does not write down the data.
As shown in the picture, the Worksheet is set to nothing. How do I set the worksheet according to the selected person from the combobox?
Public Sub CommandButton1_Click()
Dim lRow As String
Dim Rng As Range
Dim Rng2 As Range
Dim ws As Worksheet
Set ws = ComboBox1.List(I, 0)
Set Rng = Range("C4, C53")
Set Rng2 = Range("E4, Q53")
lRow = ws.Cells(Rows.Count, 1).End(xlUp).Row
With ws
Rng.Cells.lRow.Value = Format(Time, "DD:MM:YYYY:HH:MM")
End With
End sub
I assume that your list contains names of worksheets for each person, like {"Monica", "Adam"...}, right?
The problem in your case is that you try to use string value from ComboBox1 to define worksheet which is an object in worksheets collection.
You should get string value (name) of worksheet and then use it to set your ws object.
Here is simple code snippet, hope it is what you wanted to achieve :)
Private Sub ComboBox1_click()
Dim ws As Worksheet
'Define worksheet from worksheets collection
Set ws = worksheets(ComboBox1.Value)
ws.Range("A5").Value = "Hello!"
End Sub
Private Sub UserForm_Initialize()
Dim ws As Worksheet
'Make list of all worksheets
For Each ws In worksheets
ComboBox1.AddItem ws.Name
Next ws
End Sub
Related
I am trying to sum values from my original worksheet in specific cells in my newly created worksheet, which has a template to fill out.
When I used macro recorder, it references the worksheet name, which would not be useful as the worksheet name changes depending on which worksheet I am working in when I run the code.
So I tried changing the worksheet name to a variable "XCXX".
The first argument works so I thought everything was okay, however, on the second argument, it keeps trying to open a file, when it should simply go back to XCXX and pull the values.
Is it a problem with my activesheet changing?
Sub AddWorkbooks()
Dim ChangeOrder As Range
Dim XCXX As Worksheet
Dim CoForm As Worksheet
Set XCXX = ActiveSheet
Set CoForm = Worksheets("+CO Form+")
'Set wbNew = Workbooks.Add
CoForm.Copy After:=Sheets(ActiveSheet.Index)
With CoForm
Range("A6:D6").Select
ActiveCell.FormulaR1C1 = XCXX.Range("D2").Value
Range("AD81").Select
ActiveCell.FormulaR1C1 = "='XCXX'!R[-64]C[-24]+'XCXX'!R[-64]C[-23]"
End With
End Sub
This should be close:
Sub AddWorkbooks()
Dim ChangeOrder As Range
Dim XCXX As Worksheet, wb As Workbook
Dim CoForm As Worksheet, CoFormCopy As Worksheet
Set wb = ActiveWorkbook
Set XCXX = ActiveSheet
Set CoForm = wb.Worksheets("+CO Form+")
CoForm.Copy After:=XCXX
Set CoFormCopy = XCXX.Next 'the copy of "+CO Form+"
With CoFormCopy 'assuming you want to work with the copy?
.Range("A6:D6").Value = XCXX.Range("D2").Value
.Range("AD81").FormulaR1C1 = _
Replace("='<nm>'!R[-64]C[-24]+'<nm>'!R[-64]C[-23]", "<nm>", XCXX.Name)
End With
End Sub
Note when using With you need to use a period to link (eg) Range() with the object used in the With statement, otherwise it defaults to the active sheet.
Also generally there's no need to select a range to do something with it.
I am trying to take a sheet like:
A3,B3,C3 are the sum of the 2 values above them.
Copy this entire sheet into another sheet with only static values ie the sum formulas are gone and 5,73,55 are just the values.
Public Sub CopyEntireSheetValues()
Sheets("Static Data").Range("A1:M100").Value = Sheets("MAIN").Range("A1:M100").Value
End Sub
This works but ideally, i wouldn't define this range and copy all values from one sheet to another
Here's commented code for how I'd accomplish this task via .UsedRange
Sub CopyEntireSheetValues()
'Define and declare workbook and worksheet variables
Dim wb As Workbook: Set wb = ThisWorkbook
Dim wsSrc As Worksheet: Set wsSrc = wb.Worksheets("Main")
Dim wsDst As Worksheet: Set wsDst = wb.Worksheets("Static Data")
'Set the range you want to copy values from
Dim rCopy As Range: Set rCopy = wsSrc.UsedRange
'Bring only the values to the destination sheet
wsDst.Range("A1").Resize(rCopy.Rows.Count, rCopy.Columns.Count).Value = rCopy.Value
End Sub
Two ways. The exact method to do what you want is use the pastespecial method which would be as follows:
Public Sub CopyEntireSheetValues()
Sheets("MAIN").Range("A1:C100").Copy
Sheets("Static Data").Range("A1").PasteSpecial (xlPasteValues)
End Sub
The other is as explained in comment just setting values.
Sheets("Static Data").Range("A1:C100").Value = Sheets("MAIN").Range("A1:C100").Value
In general the setting values is probably the best. The only time I've used the pasteValues is sometimes dates don't quite behave the same when using the second method, but the end result should be the same.
You updated your question, but this could be dynamic (I didn't test).
Public Sub CopyEntireSheetValues()
Sheets("MAIN").UsedRange.Copy
Sheets("Static Data").Range(Sheets("MAIN").UsedRange.Address).PasteSpecial (xlPasteValues)
End Sub
this might be answered already from other posts I have read but still struggling to figure it out.
I have a workbook with 85 worksheets on it. Each sheet is like an invoice format, meaning it is not formatted as a normal data set. In order for me to get the data only I need, i created helper columns which only selects the data I need for consolidation. So I have a range I13:N42 which contains the data I need to consolidate.
At the end of the workbook, I already set up a Master Sheet with all the necessary headers for the data set. And there are 2 more worksheets namely "Tracking" & "AppControl" but I dont want them to be included in the loop together with the Master sheet.
For my range (filled with cell references/formulae), I need to copy only the row that has data in it.
You might have some ideas to improve the code I am currently using.
Sub Combine()
Dim i As Integer
Dim ws As Worksheet
Dim rng As Range
On Error Resume Next
For i = 1 To Sheets.Count
Sheets(i).Activate
Range("I13:N42").Select
Selection.Copy Destination:=Sheets("Master").Range("A65536").End(xlUp)(2)
Next i
End Sub
First remove On Error Resume Next. This line hides all error messages but the errors still occour, you just cannot see their messages. So if there are errors you cannot see you cannot fix them. If you don't fix them your code cannot work. Remove that line and fix your errors! Also see VBA Error Handling – A Complete Guide.
Second Avoid using Select in Excel VBA. That is a very bad practice and makes your code unreliable!
Option Explicit
Public Sub Combine()
Dim wsMaster As Worksheet ' set master worksheet
Set wsMaster = ThisWorkbook.Worksheets("Master")
Dim ExcludeWorksheets As Variant ' define worksheets names to exclude
ExcludeWorksheets = Array(wsMaster.Name, "Tracking", "AppControl")
Dim i As Long
For i = 1 To ThisWorkbook.Worksheets.Count
If Not IsInArray(ThisWorkbook.Worksheets(i).Name, ExcludeWorksheets) Then 'exclude these worksheets
ThisWorkbook.Worksheets(i).Range("I13:N42").Copy Destination:=wsMaster.Cells(wsMaster.Rows.Count, "A").End(xlUp)(2)
End If
Next i
End Sub
Public Function IsInArray(ByVal StringToBeFound As String, ByVal Arr As Variant) As Boolean
IsInArray = (UBound(Filter(Arr, StringToBeFound)) > -1)
End Function
Alternatively you can use a For Each loop which looks a bit cleaner then
Option Explicit
Public Sub Combine()
Dim wsMaster As Worksheet ' set master worksheet
Set wsMaster = ThisWorkbook.Worksheets("Master")
Dim ExcludeWorksheets As Variant ' define worksheets names to exclude
ExcludeWorksheets = Array(wsMaster.Name, "Tracking", "AppControl")
Dim ws As Worksheet
For Each ws Is ThisWorkbook.Worksheets
If Not IsInArray(ws.Name, ExcludeWorksheets) Then 'exclude these worksheets
ws.Range("I13:N42").Copy Destination:=wsMaster.Cells(wsMaster.Rows.Count, "A").End(xlUp)(2)
End If
Next ws
End Sub
I have a Macro (within a Master Workbook) that is getting data from another Workbook/Worksheet using .value2.
I've tried different changes, within the code. I double checked that both workbooks are open. However, I keep getting the Subscript out of range (Error 9).
Sub NielsenScorecard_DataPaste()
Dim WbNielsenScorecard As Workbook
Set WbNielsenScorecard = Workbooks("Nielsen Scorecard_Template.xlsm")
TotalUS_DataPaste
End Sub
Sub TotalUS_DataPaste()
**Subscript out of range (Error 9)**
With Workbooks("Power Query - Meijer_Walmart_Total US xAOC.xlsm").Worksheets("PQTotalUS")
Dim Data(0) As Variant
'Copy Data Range
Data(0) = .Range(.Cells(.Rows.Count, "A").End(xlUp), "AA2").Value2
End With
'Worksheet Code Name within this Workbook
With wsTotalUS
Debug.Print wsTotalUS.Name
.AutoFilter.ShowAllData
.Range("A2:AA" & .Cells(.Rows.Count, "A").End(xlUp).Offset(1).Row).ClearContents
With .Cells(.Rows.Count, "A").End(xlUp).Offset(1).Resize(UBound(Data(0)))
.Resize(ColumnSize:=UBound(Data(0), 2)).Value2 = Data(0)
End With
End With
End Sub
You can reference a sheet by its codename, however it is a different format and must be in ThisWorkbook. A drawback is that you cannot reference a sheet in another workbook by its codename. Worksheets("PQ Total US").Activate versus PQTotalUS.Activate. If your goal is to shorten the code and not have to repeat a long name, then another option is to do the following:
Dim wb1 as Workbook
Dim ws1 as Worksheet
Set wb1 = Workbooks("Power Query Meijer_Walmart_Total US xAOC.xlsm")
Set ws1 = wb1.Worksheets("PQ Total US")
With ws1
'Do something
End with
I am currently working on macro in a workbook with multiple worksheets, that aims to show and hide certain worksheets based on the values in a master worksheet. The worksheet names are also contained in the master worksheet and the main procedure looks at these values when referencing to a worksheet it needs to show or hide. The problem with this method is that, the macro will produce errors if the user changes the worksheet tab names. I was hoping to insert an additional procedure that makes the tab names of each worksheet equal to the values in the respective cell of the master worksheet. I came up with the following:
Sub SheetName()
If Not ActiveWorkbook Is ThisWorkbook Then Exit Sub
Dim DataImport As Worksheet
Set DataImport = ThisWorkbook.Worksheets("Data Import")
DataImport.Range("A13").Value = Sheet1.Name
End Sub
This code works fine but there are about 100+ worksheets in this workbook. I was wondering if there is a more efficient way to do this, as opposed to typing the same procedure 100 times. I've tried storing the worksheet code names in an array and looping the same procedure through the array, for example:
Sub test()
Dim DataImport As Worksheet
Set DataImport = ThisWorkbook.Worksheets("Data Import")
Dim index As Long
Dim ws(0 To 2) As Worksheet
Set ws = Array(Sheet1, Sheet2, Sheet3)
For i = 13 To 14
index = i - 13
DataImport.Cells(i, "A").Value = ws(index).Name
Next i
End Sub
but the error message "Can't Assign to Array" shows up. Sorry in advance if my code looks garbage, I am still new to VBA and I still have quite a lot to learn.
If you list the sheet codenames in ColA of your master sheet, then this code will update columns B and C with the current sheet tab names and indexes respectively:
Sub UpdateIndex()
Dim ws As Worksheet, cn As String, m
For Each ws In ThisWorkbook.Worksheets
cn = ws.CodeName
If cn <> DataImport.CodeName Then
'look for the codename in the Import sheet
m = Application.Match(cn, DataImport.Columns(1), 0)
If Not IsError(m) Then
'got a match - update this row
DataImport.Cells(m, "B").Value = ws.Name 'tab name
DataImport.Cells(m, "C").Value = ws.Index 'sheet index
End If
End If
Next ws
End Sub
Assumes you set the code name for your "Data Import" worksheet to DataImport.
If your code is driven by the sheet codename, it doesn't matter whether the user renames the tabs or changes the sheet order.
For your second attempt, you can use Excel built-in Sheets object and Workbook.Sheets collection:
Sub test()
Dim DataImport As Worksheet
Set DataImport = ThisWorkbook.Worksheets("Data Import")
Dim index As Long
Dim ws As Excel.Sheets
Set ws = ThisWorkbook.Sheets
For i = 13 To 14
index = i - 13
DataImport.Cells(i, "A").Value = ws(index).Name
Next i
End Sub