refresh a textbox VBA - vba

I want a macro that creates a textbox in Worksheet2 when I write something in Worksheet1!A1. The problem is that I want it to refresh whenever I refresh the data.
I made one but is runs the macro again, so I am left with several textbox, one on top of the others. Also I want to delete the textbox if the cell is empty.
I would appreciate any help. Thanks. Here is my code:
Sub criarcaixastexto()
Dim wsActive As Worksheet
Dim box As Shape
Set wsActive = Worksheets(2)
Set box = wsActive.Shapes.AddTextbox(msoTextOrientationHorizontal, 20, 20, 100, 50)
box.TextFrame.Characters.Text = Range("Folha1!A1").value
End Sub
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$A$1" Then
Call criarcaixastexto
End If
End Sub

To ignore empty values change the event to this one:
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Count > 1 Then Exit Sub 'to avoid multiple selection.
If Target.Address = "$A$1" Then
RemoveShapes
If Len(Target) > 1 then Criarcaixastexto
End If
End Sub
This will remove the shapes, before writing new ones.
Sub RemoveShapes()
Dim shp As Shape
For Each shp In Worksheets(2).Shapes
If shp.Type = msoTextBox Then shp.Delete
Next shp
End Sub

Related

VBA loop in change event error

I have this macro that creates a textbox in worksheet 2 when I write something in cell A1 of worksheet 1, and when I delete that value it deletes the textbox.
I want to do that for several cells, but it just is working. If Cell A1 has a value a textbox with that value should appear, if the A2 has a value a textbox with that value should appear, but if I delete A1 it should delete the texbox that refers to A1, not all of the textboxes
Sub RemoveShapes()
Dim shp As Shape
For Each shp In Worksheets(2).Shapes
If shp.Type = msoTextBox Then shp.Delete
Next shp
End Sub
Sub criarcaixastexto()
Dim wsActive As Worksheet
Dim box As Shape
Set wsActive = Worksheets(2)
Set box = wsActive.Shapes.AddTextbox(msoTextOrientationHorizontal, 20, 20, 100, 50)
box.TextFrame.Characters.Text = Range("Folha1!A1").value
End Sub
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$A$1" Then
Call criarcaixastexto
End If
End Sub
I tried this but it doesn't work
'macro para apagar
Sub removercaixas()
Dim shp As Shape
For Each shp In Worksheets(2).Shapes
If shp.Type = msoTextBox Then shp.Delete
Next shp
End Sub
'macro para criar caixas de texto
Sub criarcaixastexto()
Dim wsActive As Worksheet
Dim box As Shape
Set wsActive = Worksheets(2)
Set box = wsActive.Shapes.AddTextbox(msoTextOrientationHorizontal, 20, 20, 100, 50)
box.TextFrame.Characters.Text = Worksheets(1).Cells(i, 1).Value
End Sub
' macro corre ao escrever texto numa célula
Private Sub Worksheet_Change(ByVal Target As Range)
For i = 1 To 3
If Target.Count > 1 Then Exit Sub
If Not Intersect(Target, Range("A&i")) Is Nothing Then
removercaixas
If Len(Target) > 1 Then criarcaixastexto
End If
Next
End Sub
You are removing all textboxes on the sheet any time you call removercaixas. You need to somehow link the textbox with the cell it was generated by.
Why not name the textbox with the cell address? Copy/Paste this:
Sub removercaixas(strName As String)
Dim shp As Shape
For Each shp In Worksheets(2).Shapes
If shp.Type = msoTextBox AND shp.Name = strName Then shp.Delete
Next shp
End Sub
And
Sub criarcaixastexto(strName As String)
Dim wsActive As Worksheet
Dim box As Shape
Set wsActive = Worksheets(2)
Set box = wsActive.Shapes.AddTextbox(msoTextOrientationHorizontal, 20, 20, 100, 50)
box.TextFrame.Characters.Text = Worksheets(1).Range(strName).Value
box.Name = strName
End Sub
And
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Count > 1 Then Exit Sub
Select Case Target.Address
Case "$A$1", "$A$2", "$A$3"
removercaixas (Target.Address)
Case Else
Exit Sub
End Select
If Len(Target) > 1 Then criarcaixastexto (Target.Address)
End Sub
Textboxes are created in worksheet 2 all on top of each other. They are deleted appropriately. No textbox is created when the value entered in $A$1:$A$3 has a length of 1 or less. Not sure what the logic is there, but if you want single digit values to create a textbox just change the Len(Target) > 1 to Len(Target) > 0.

Multiple cell value change to trigger macros

I have different set of values in cells G3:G4 and D15:D10000 in a single sheet. I want run two separate codes when G columns or D columns are changed. How I can identify which set of columns are changed?
out this in your worksheet code pane
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("G3:G4")) Is Nothing Then
'code when some cell in range "G3:G4" is changed
ElseIf Not Intersect(Target, Range("D15:D10000")) Is Nothing Then
'code when some cell in range "D15:D10000" is changed
End If
End Sub
Put the code below in your relevant worksheet, in the Worksheet_Change event.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim WatchRange As Range
Dim IntersectRange As Range
Set WatchRange = Application.Union(Range("G3:G4"), Range("D15:D10000"))
Set IntersectRange = Intersect(Target, WatchRange)
If Not IntersectRange Is Nothing Then
Select Case Target.Column
Case 4 ' column D
Call A
Case 7 ' column G
Call B
End Select
End If
End Sub
Below are examples of Sub A and Sub B:
Sub A()
MsgBox "Running Sub A"
End Sub
Sub B()
MsgBox "Running Sub B"
End Sub

VBA - Open a UserForm by clicking anywhere in a specific column

I would like to build a makro in VBA which opens a UserForm when I click in a cell in a specific column, for more details look here.
With this code (from Mr.Burns):
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Selection.Count = 1 Then
If Not Intersect(Target, Range("A1")) Is Nothing Then
'name of userform .Show
End If
End If
End Sub
I was able to open the UserForm by clicking in the cell A1, but not by clicking in any cell inside the column A.
I tried to solve this problem with this code:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Selection.Count = 1 Then
Dim check As Boolean
check = True
If check Then
Dim i As Long
For i = 1 To 100000
If Not Intersect(Target, Range("A" & i)) Is Nothing Then
UserForm1.Show
check = False
End If
Next
End If
End If
End Sub
It actually works fine, but it is very slow, is there any better possibility to solve this?
To display the form when a cell is selected in column A:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
' if target is one cell and in column A
If Target.Columns.count = 1 And Target.Rows.count = 1 And Target.Column = 1 Then
UserForm1.Show
End If
End Sub
You can use .count and .column property together with AND and it will become so much simple and fast. Following code triggers pop-up if u click in column A on active-sheet
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
On Error GoTo errorhandler
If Target.Count = 1 And Target.Column = 1 Then '.count to check if only one cell is selected and .column to check if it is a first column
'UserForm1.Show
'Do whatever you want to do here like opening User form
MsgBox "You clicked in column A"
End If
errorhandler:
End Sub

Add hyperlink to an image via cell in Excel

is there a way to add a hyperlink, provided from a cell, to an image?
I tried the following VBA code:
Sub Storage_Test_Click()
ActiveSheet.Hyperlinks.Add Anchor:=storage_image, Address:=Worksheets("Links").Range("B8:B8").Value
End Sub
But with this piece of code, the link is persistent. In other words, if I change the cell value, the link from the image is not affected.
Thanks,
Tro
Enter something like this in a Module
Sub Add_HLink(ws As Worksheet, picture_name As String)
Dim sh As Worksheet: Set sh = Worksheets("Link")
Dim shp As Shape
For Each shp In ws.Shapes
If shp.Type = msoPicture And shp.Name = picture_name Then
ws.Hyperlinks.Add shp, sh.Range("B8").Value
Exit For
End If
Next
End Sub
Then in your Link Sheet:
Private Sub Worksheet_Change(ByVal Target As Range)
On Error GoTo halt
Application.EnableEvents = False
If Not Intersect(Target, [B8]) Is Nothing Then
'~~> use the sub here, assuming Picture named "Picture 1" is in Sheet2
Add_HLink Sheet2, "Picture 1" '~~> change the arguments to suit
End If
continue:
Application.EnableEvents = True
Exit Sub
halt:
MsgBox Err.Description
Resume continue
End Sub
Is this what you're trying? HTH.
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
ActiveSheet.Hyperlinks.Add Anchor:=storage_image, Address:=Worksheets("Links").Range("B8:B8").Value
End Sub
dont assign the macro to the image, because you can't click on the image (as it's a hyperlink!), if you right click your image with your original code after updating your link, im sure that selects it and your macro will run, however the above changes should mean everytime you make a selection on your sheet, your links will update

Create Temporary Excel Chart

Sub aaGraphing()
'
' aaGraphing Macro
'
'
Range("L948:W949,D948:D949").Select
Range("D949").Activate
ActiveSheet.Shapes.AddChart.Select
ActiveChart.ChartType = xlLineMarkers
ActiveChart.SetSourceData Source:=Range( _
"Analytics!$L$948:$W$949,Analytics!$D$948:$D$949")
End Sub
This code creates a chart of the data I want. Is there a way to way to make the created chart temporary so that when you click anywhere outside of the chart it deletes?
You could use the SelectionChange event of the worksheet to delete the chart. Below I am assuming there is only one shape - the chart - that might be on the worksheet.
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Me.Shapes.Count = 1 Then
Me.Shapes(1).Delete
End If
End Sub
It is possible (I believe) to dynamically attach this event, and remove it. However, I believe that it is a little complicated.
An alternative might be to use Application.OnTime to delete it after a period of time.
Application.OnTime Now + TimeValue("00:00:40"), "ProcedureToDelete"
will run the procedure named 'ProcedureToDelete' after 40 seconds. In this procedure you might want to make sure the the selection is in the worksheet, not in the chart that you are about to delete.
You could, in the timed-procedure, check to see if the chart is currently selected. If not, delete it, otherwise set the timer again.
Regular module....
Option Explicit
Public PlotName As String
Public PlotRange As Range
Sub Tester()
AddPlot ActiveSheet.Range("B3:B7,D3:D7")
End Sub
Sub AddPlot(rng As Range)
With ActiveSheet.Shapes.AddChart
PlotName = .Name
.Chart.ChartType = xlLineMarkers
.Chart.SetSourceData Source:=Range(rng.Address())
End With
Set PlotRange = rng
Application.EnableEvents=False
rng.Select
Application.EnableEvents=True
End Sub
Sub RemovePlot(rng As Range)
If Not PlotRange Is Nothing Then
If Application.Intersect(rng, PlotRange) Is Nothing Then
On Error Resume Next
rng.Parent.Shapes(PlotName).Delete
On Error GoTo 0
End If
End If
End Sub
Sheet code module:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
RemovePlot Target
End Sub