I have used a vba code to add a new row with from control button in column A.
the code is working fine but has a small issue.
I am trying to change button name property during copy but I dont know how to do it ?
For example, I am copying a button with name “validate”, when it will be copied to next row I want to change the Name property (not the button text) of the button to “validate1”.
can you please let me know how to do it ?
Dim Lr As Integer Dim newLr As Integer Dim lim, rng, sht, btn As String Lr = Range("B" & Rows.Count).End(xlUp).Row 'Searching last row in column A newLr = Lr + 1 lim = "B" & newLr & ":" + "D" & newLr rng = "A" & newLr Rows(Lr).Copy Rows(newLr).Insert 'Range(lim).ClearContents sht = ActiveSheet.Name btn = "validate" & newLr Application.ScreenUpdating = False Sheets(sht).Shapes("validate").Copy Sheets(sht).Activate Sheets(sht).Range(rng).Select Sheets(sht).Paste Sheets(sht).Shapes("validate").Select Selection.Characters.Text = btn Application.ScreenUpdating = True
Image link: https://ibb.co/c0rFfv
After you paste the shape, simply write the code below.
Sheets(sht).Shapes(.Shapes.Count).Name = btn
Because when you add a new shape, it has the highest index. So if you
find the highest indexed shape by
.Shapes.Count, then you can rename it easily.
And Some other recommendations based on VBA Best Practices:
1 – Always Use Option Explicit
Because If you were using it, you would see that your
"lim,rng,sht" variables were not defined.
Commas = ",' are not enough to define all of your variables. You need to declare them separately one by one. So instead of
Dim lim, rng, sht, btn As String use
Dim lim as String, rng as String, sht as String, btn As String
2 – Work with Long instead of Integer
Because Excel might need your Integer to Long to run the code in newer versions of Excel. You can simply avoid it at first by defining your variables as Long instead of Integer.
3 – Never Assume Worksheet
Don’t rely on ActiveWorkbook or ActiveSheet as they might be changed
by the user.
The best practice is to always identify which worksheet to which your code refers:
So in your example:
Dim wb as Workbook, ws as Worksheet Set wb = ThisWorkbook Set ws = wb.Sheet("Sheet1") Lr = ws.Range("B" & Rows.Count).End(xlUp).Row
kind of approach will never mislead you.
4 – Avoid Using Select or Activate
.Select() is slow
.Select() is unruly
.Select() will trigger listeners
5 – Use descriptive variable naming
Descriptive names and structure in your code help make comments unnecessary.
So your code would be much more clear and efficient in that way:
Option Explicit Application.ScreenUpdating = False 'It's better to switch off properties from starting of your macro Dim wb as Workbook, ws as Worksheet Dim Lr As Long Dim newLr As Long Dim sht as String, btn As String Dim lim as Range, rng as Range 'Using these ones directly as a Range is better idea. Set wb = ThisWorkbook Set ws = wb.Sheets("Sheet1") Lr = ws.Range("B" & Rows.Count).End(xlUp).Row 'Searching last row in column A '==> if you would like to count rows in A, then change your code. Now it's looking for "B". newLr = Lr + 1 set lim = ws.Range("B" & newLr & ":" + "D" & newLr) set rng = ws.Range("A" & newLr) ws.Rows(Lr).Copy ws.Rows(newLr).Insert 'Range(lim).ClearContents sht = ws.Name btn = "vaalidate" & newLr With Sheets(sht) .Shapes("validate").Copy .rng.Paste .Shapes(.Shapes.Count).Name = btn End With Application.ScreenUpdating = True
There’s no need to use
Sheets(sht).Range(rng).Select it only slows down your code run-time, instead use fully qualified
Worksheets, like the code below:
With Sheets(sht) .Shapes("validate").Copy .Paste .Shapes(.Shapes.Count).Name = btn End With
After the line
Selection.Characters.Text = btn, add
Selection.Name = btn.