I have a VBA code in a sheet that is activated when a cell is changed. But this sheet is re-created by another macro, and when the sheet is re-created it does not have the VBA code inside the sheet.
Then I was looking for two solution (I don't know how to do it and did not find anything on the web, then I ask here):
a way to automatically copy and past the VBA code so the the new sheet created by the macro will have the VBA code
or call the VBA code that can be stored in a module (don't know even if it is possible, since is "Private Sub Worksheet_Change(ByVal Target As Range)")
Just to clarify better, below the VBA code that is inside the sheet that is re-created by a macro
Public Sub Worksheet_Change(ByVal Target As Range)
Dim sht As Worksheet
Dim LastRow As Long
Dim isect As Range
Dim firstCell As Range
modulo = ActiveSheet.Offset(-1, -3).Value
tipo = ActiveSheet.Offset(-1, -2).Value
nome = ActiveSheet.Offset(-1, -1).Value
descrizione = ActiveSheet.Offset(-1, 0).Value
Worksheets(modulo).Activate
Range(A1).Select
With ActiveSheet
.Range("A1:E10000").AutoFilter Field:=1, Criteria1:=modulo
.Range("A1:E10000").AutoFilter Field:=2, Criteria1:=tipo
.Range("A1:E10000").AutoFilter Field:=3, Criteria1:=nome
ActiveSheet.UsedRange.Offset(1, 3).SpecialCells(xlCellTypeVisible)(1).Value = descrizione
End With
UserForm3.Show
End Sub
Thanks!
a) For an example on how to copy code see Copy VBA code from one Worksheet to another using VBA code
b) You can copy code, but you need to set "Trust Access To Visual Basics Project". How to do so, see https://stackoverflow.com/a/11680865/7599798. Be aware that this is an individual setting (per user) and therefore you cannot be sure that this works for all user.
c) Your attempt to put the code into a module will not work. Event routines need to be in the Workbook/Worksheet where the event happens. If the new sheet is copied into a Workbook where you have already code, you could use the
Workbook_SheetChange event which is triggered at any change on any sheet within the workbook.
d) If the (re)creation of the sheet is done by a macro that you control: Instead of adding a new sheet, copy an existing template sheet that already contains code.
Related
I am trying to get a database from Workbook B to autofilter using some input from Workbook A. I am building the macro in Workbook A.
I have the following:
Workbook A - Document were you start working
Worrkbook B - Database, the final objective of this code is to import some info from Workbook B to Workbook A
I need the following:
By double clicking in a column from workbook A, workbook B should open (done)
The clicked value from workbook A will be saved as a variable, lets call it input_db (done)
Workbook B will autofilter based on input_db (not done, help required here!)
The required data is selected from workbook B and imported to workbook A, preferably with a double click as well (not done yet, but if you have any suggestion for this, Ill be gratefull ;))
The process should be repeated several times in a row.
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
Dim input_row, input_column As Integer
Dim input_db As String
Dim wbB, wbA As Workbooks
If Not (Application.Intersect(ActiveCell, [Links]) Is Nothing) Then 'Links is the name of the range where I need the code to be active
If ActiveCell.Value <> "" Then
input_row = ActiveCell.row
input_column = ActiveCell.Column
input_db = ActiveCell.Value
Set database = Workbooks.Open("Workbook B location")
ActiveWorkbook.ActiveSheet.Range("A9").AutoFilter Field:=1, Criteria:=input_db ' This bit doesnt work as expected
End If
End If
End Sub
As I can see you are using the wrong format of Autofilter. Try this line after amending as per your need. Autofilter takes in Criteria1 not Criteria.
ActiveWorkbook.ActiveSheet.Range("A9").AutoFilter Field:=1, Criteria1:=input_db
Also you can find more about Autofilter here: Link
Let us know if it still doesn't work.
Edit 2 :
You will have to open a input box and select the cell. You can follow the This Link for that.
I'm trying to create a series of macros to audit some financial models.
The first macro I’m trying to create is one that names the current cell. Why? I want to name the cell, after that I’m going to record a macro to click the “Trace Precedents” and go to the cell that has the relationship.
After that I need to go back to the original cell, thats the named one. That's easy on the go function, but I need to the naming macro working
My recorded code for the naming macro is as follows:
Sub Namer ()
ActiveWorkbook.Names.Add Name:="Name1", RefersToR1C1:="=Workings!R42C6"
ActiveWorkbook.Names("Name1").Comment = ""
End Sub
I have the following problems:
I need to name the current cell on a workbook with a lot of sheets. I’m gonna be moving between sheets but my recorded code has a “fixed” sheet.
How can I fix that? Name the current cell on the current sheet
Something like this should help you ...
Public Sub CreatesNames()
Dim objSheet As Worksheet
For Each objSheet In ThisWorkbook.Worksheets
objSheet.Names.Add Name:="Name1", RefersTo:=objSheet.Range("A1")
Next
End Sub
... something to note, names can be created at the worksheet level or at the workbook level, so, if you're going to be creating the same name across worksheets then you need to use a Worksheet object, not the Workbook object.
So to use the active cell ...
Sheet Level
ActiveSheet.Names.Add Name:="Name1", RefersTo:=ActiveCell
Workbook Level
ActiveWorkbook.Names.Add Name:="Name1", RefersTo:=ActiveCell
I hope that helps.
I'm very new to DBA so probably it's a banal mistake but I looked around and I did not found anything that could help me.
I'm trying to populate a combobox dynamically using the content of a column (column "A" in this specific case) using a macro linked to a button. If the analyzed cells are empty everything goes smoothly and the message "done!" appears, but if there is any data in the cells I get the error "424 object required access".
I don't know if it would help: I took the code from this youtube video https://www.youtube.com/watch?v=x8O59GtatH8 and adapted it (just removed the listox) the complete code is at 5.35
I'm probably misunderstanding something very basic. I am guessing the declaration of the combobox.
Sub prova_stessa_scheda()
row_review = 1
Dim TheSheet As Worksheet
Set TheSheet = Sheets("Listino_prezzi")
Do
DoEvents
row_review = row_revieew + 1
item_in_review = TheSheet.Range("A" & row_review)
If Len(item_in_review) > 0 Then ComboProva_Change.AddItem (item_in_review) 'this is the command that gives the error
Loop Until item_in_review = ""
MsgBox "Done!"
End Sub
I expected that when the macro gets triggered the combobox gets filled with the value written in the cells of column "A" instead I got the error 424.
If you put your code into the Worksheet module of the sheet where the combobox is placed, VBA is assuming that you want to access the element CombProva of that sheet (this is what is done in the video, only with different names).
However, if you put your code into a regular module, VBA does not know what CombProva is. You have to tell VBA that you want to access it from a specific sheet. There are several ways to do so:
(1) Use
With ThisWorkbook.Sheets("Listino_prezzi")
.ComboProva.AddItem (item_in_review)
End With
Note that the following code will throw an compiler error. This is because TheSheet is of type Worksheet, so it could be any worksheet, and a worksheet does not have anything named ComboProva.
Dim TheSheet As Worksheet
Set TheSheet = Sheets("Listino_prezzi")
With TheSheet
.ComboProva.AddItem (item_in_review) ' <-- Compiler error
End With
(2) You can access the sheet also by its CodeName. If you look to the video: The sheet itself was renamed to Admin Site, but the CodeName is still Sheet1 (the CodeName can only be changed in the VBA editor in the Property-window). So you can write
With Sheet1
.ComboProva.AddItem (item_in_review)
End With
(3) You can access the combobox by name from the Shapes-collection of the sheet (basically everything that is put on a sheet but not within an cell is a Shape). However, as you are dealing with ActiveX-controls, this is a little bit ugly.
Dim sh as Shape
Set sh = TheSheet.Shapes("ComboProva")
With sh.DrawingObject.Object
Call .AddItem("Variante x")
End With
I have a spreadsheet that is used to log information. In one sheet you enter the data then VBA updates a second sheet where the info is stored.
I want to write a code that will check if a cell on the last row of the log (which will be changing as it updates each time) equals a cell on the input page.
The aim is to stop someone updating the log twice, I already have an alert that it has been updated but want to put a foolproof system in place to stop an entry being logged twice.
I am new to VBA so do not really know where to start.
The below is an example of achieving this. I have added comments to explain what is happening in the VBA.
In Excel, press Alt+F11
In the project window on the left, expand it if its not already and
double click on 'ThisWorkbook'
If it is not already there, type Option Explicit as the first
thing in the main window. This means the code will not run unless
all variables that are used are declared, this is good practice
Past the below code into the window
With the cursor in the code you can press F8 to run it line by line
to see what is happening or F5 to run it in one go.
You will want to adjust it to your required workbooks, worksheets, and cells/columns.
Public Sub Sample()
'Clearly declare variables, in the case we are using them
'to reference a workbook and a worksheet
Dim WkBk As Workbook
Dim WkSht As Worksheet
'Set the WkBk variable (which was declared as a workbook,
'which means it can only be used for workbook objects.
'I this instance we are refering to ThisWorkbook,
'which is as it sounds.
Set WkBk = ThisWorkbook
'We can now make a reference to a specific worksheet
'within our referenced workbook
Set WkSht = WkBk.Worksheets("Sheet2")
'This IF statement is comparing the value of cell
'A1 on Sheet1 to the the value of the last populated cell
'in column A of Sheet2 (the sheet we created a reference to)
If WkBk.Worksheets("Sheet1").Range("A1") = WkSht.Range("A" & WkSht.Rows.Count).End(xlUp) Then
MsgBox "It was a match"
End If
Set WkSht = Nothing
Set WkBk = Nothing
End Sub
I'm a very new, self-taught programmer, so please keep this in mind in your responses. I have extensively searched this and other forums and can't seem to find a similar question.
The following code has been working for weeks and has not been changed. (My macro includes more variables and code, but I know from taking it apart that those pieces work, so I've left them out for clarity). From what I can tell the PasteSpecial function is specifically not working.
Dim StimSheet As String
ActiveCell.Rows("1:290").EntireRow.Select
Selection.Copy
'Copies the data for the current stimulus
StimSheet = Application.InputBox("Enter the name of the stimulus")
'asks name of the stimulus
Sheets.Add After:=Worksheets(Worksheets.Count)
ActiveSheet.Name = StimSheet
'adds new sheet at the end and names whatever you input as stimulus name
Sheets(StimSheet).Select
Selection.PasteSpecial Paste:=xlPasteValues
'pastes data into new sheet
At this point there is no error, the macro simply stops after copying and creating the new sheet.
Here's what I know / have tried:
The macro is successfully making and naming the new sheet and copying the selection to the clipboard, because I can manually paste it after running the macro. It seems to be getting stuck at the paste piece.
Other macros that use the exact same format of copy / paste special are still working correctly.
Another forum with a similar program suggested typing "Application.EnableEvents=True" into the immediate window. This did not change anything.
This macro has worked for several weeks with no errors. I have made new macros using previously saved code in case something inadvertently was changed in the current one, but this did not work either.
The paste option will work one time on a new file and then ceases to work again.
Thank you in advance for your suggestions.
You might find the problem is that you don't have much control over which workbook and worksheet this code applies to. It's better to avoid ActiveSheet, Select, and Sheet with no parent as much as you can.
If you only need to copy the values of cells without any formatting, then Paste isn't needed either.
Try changing your code to the following and see if you have any better luck:
Const BOOK_NAME As String = "Book1.xlsm" 'change this to your workbook name
Const SOURCE_SHEET_NAME As String = "Sheet1" 'change this to your sheet name
Dim wb As Workbook
Dim sourceSheet As Worksheet
Dim newSheet As Worksheet
Dim newSheetName As String
Dim validName As Boolean
Dim rng As Range
' Set the book, sheet and range objects
Set wb = Workbooks(BOOK_NAME)
Set sourceSheet = wb.Worksheets(SOURCE_SHEET_NAME)
Set newSheet = wb.Worksheets.Add(After:=wb.Worksheets(wb.Worksheets.Count))
' Acquire the new sheet name and check it's valid.
Do
newSheetName = InputBox("Enter the name of the stimulus")
On Error Resume Next
newSheet.Name = newSheetName
validName = (Err.Number = 0)
On Error GoTo 0
If Not validName Then MsgBox "Sheet name isn't valid. Try again."
Loop Until validName
' Write the values into the new sheet
Set rng = sourceSheet.Cells(1, 1).Resize(290, sourceSheet.UsedRange.Columns.Count)
newSheet.Range(rng.Address).value = rng.Value2
I moved this line:
StimSheet = Application.InputBox("Enter the name of the stimulus")
to the top of the method and it seems to work reliably. I wish I could tell you exactly why, but at least you can proceed. Perhaps it has something to do with the focus changing.
Also, when it failed for me (Office 2013) I got the following error:
Run-time error 1004:
Application-defined or object-defined error.
When the Sub was in a Sheet code behind, and this:
Run-time error '1004'
PasteSpecial method of Range class failed.
When pasted in a Module.