Animation of shapes in Visio via VBA - vba

Is it possible to, f.ex., rotate shapes or change different (boolean) settings like visibilty by giving commands via the object's ID or is prior selecting necessary?
As far as I got it, I have to select an deselect each item prior to change its characteristics/ data.
My code looks like this (shall produce an "animation" of blinking arrows):
Private Sub timeout(duration_ms As Double)
Start_Time = Timer
Do
DoEvents
Loop Until (Timer - Start_Time) >= duration_ms
End Sub
Private Sub cmd_blinking_Click()
rep_count = 0
Target = 400
blink = 0.3
Do Until rep_count = Target
DoEvents
rep_count = rep_count + 1
ActiveWindow.Select Application.ActiveWindow.Page.Shapes.ItemFromID(255), visSelect
Application.ActiveWindow.Selection.Visible = True
ActiveWindow.DeselectAll
ActiveWindow.Select Application.ActiveWindow.Page.Shapes.ItemFromID(256), visSelect
Application.ActiveWindow.Selection.Visible = False
ActiveWindow.DeselectAll
ActiveWindow.Select Application.ActiveWindow.Page.Shapes.ItemFromID(257), visSelect
Application.ActiveWindow.Selection.Visible = False
ActiveWindow.DeselectAll
timeout (blink)
ActiveWindow.Select Application.ActiveWindow.Page.Shapes.ItemFromID(256), visSelect
Application.ActiveWindow.Selection.Visible = True
ActiveWindow.DeselectAll
timeout (blink)
ActiveWindow.Select Application.ActiveWindow.Page.Shapes.ItemFromID(257), visSelect
Application.ActiveWindow.Selection.Visible = True
ActiveWindow.DeselectAll
timeout (blink*3)
ActiveWindow.Select Application.ActiveWindow.Page.Shapes.ItemFromID(255,256,257), visSelect
Application.ActiveWindow.Selection.Visible = False
ActiveWindow.DeselectAll
timeout (blink * 0.9)
Loop
End Sub
Easier way I am looking for if possible:
Private Sub timeout(duration_ms As Double)
Start_Time = Timer
Do
DoEvents
Loop Until (Timer - Start_Time) >= duration_ms
End Sub
Private Sub cmd_blinking_Click()
rep_count = 0
Target = 400
blink = 0.3
Do Until rep_count = Target
DoEvents
rep_count = rep_count + 1
ActiveWindow.Shapes.ID(255).Visible = True
ActiveWindow.Shapes.ID(256).Visible = False
ActiveWindow.Shapes.ID(257).Visible = False
timeout (blink)
ActiveWindow.Shapes.ID(256).Visible = True
timeout (blink)
ActiveWindow.Shapes.ID(257).Visible = False
timeout (blink * 3)
ActiveWindow.Shapes.ID(255).Visible = False
ActiveWindow.Shapes.ID(256).Visible = False
ActiveWindow.Shapes.ID(257).Visible = False
timeout (blink * 0.9)
Loop
End Sub

For anyone looking for "animated arrows" in VBA (as I was asking):
The function is for making a pause in between the appearance of the individual objects / shapes.
Afterwards the objects/shapes need to change their Visibility property to make an "blinking effect".
In my example I used three arrows with specific given names ("Left_Arrow_1", etc.), here the object names must be inserted. By making a macro for inserting objects an giving them defined names, this is making things easier.
Sub timeout(duration_ms As Double)
Start_Time = Timer
Do
DoEvents
Loop Until (Timer - Start_Time) >= duration_ms
End Sub
Sub blinking_arrows()
rep_count = 0
target = 400
blink = 0.3
Do Until rep_count = target
DoEvents
rep_count = rep_count + 1
Sheet1.Shapes("Left_Arrow_1").Visible = True
Sheet1.Shapes("Left_Arrow_2").Visible = False
Sheet1.Shapes("Left_Arrow_3").Visible = False
timeout (blink)
Sheet1.Shapes("Left_Arrow_2").Visible = True
timeout (blink)
Sheet1.Shapes("Left_Arrow_3").Visible = True
timeout (blink * 3)
Sheet1.Shapes("Left_Arrow_1").Visible = False
Sheet1.Shapes("Left_Arrow_2").Visible = False
Sheet1.Shapes("Left_Arrow_3").Visible = False
timeout (blink * 0.9)
Loop
End Sub

Related

Modify ms Access chart ValueAxis Minimum value

I'm struggling with charts in an Access report. The default Y axis minimum is zero, I would like to change this dynamically as the report loads.
I have tried a number of options using variations on the code below but to no avail. Could someone point me in the direction where I can access and modify the Y axis minimum value. I have tried to use Chart.PrimaryValuesAxisMaximum but this has always resulted in a 'Doesn't support this property or method' Error
Using Office Professional Plus 2019. VB 7.1
Private Sub Report_Load()
Dim MyChart As Object
Dim MyAxis As ChartAxisCollection
Set MyChart = Me.Graph4
Debug.Print MyChart.Name 'This appears to show the chart is available
Set MyAxis = MyChart.ChartAxisCollection
For Each MyAxis In MyChart
Debug.Print MyAxis.Count
Next
End Sub
Any help would be very much appreciated.
Thank you
I can give example from my project which uses classic chart control, not Modern Charts. This procedure is called by a form button click and a report Detail section Format event.
Sub FormatVibGraph(strObject As String, strLabNum As String, booMetric As Boolean)
'format Vibratory graph form and report
Dim obj As Object
Dim gc As Object
Dim MinDD As Double
Dim MaxDD As Double
MinDD = Nz(DMin("Den", "GraphVibratory"), 0)
MaxDD = Nz(DMax("Den", "GraphVibratory"), 0)
If strObject Like "Lab*" Then
Set obj = Reports(strObject)
Else
Set obj = Forms(strObject).Controls("ctrVibratory").Form
End If
Set gc = obj("gphDensity")
gc.Activate
If MinDD > 0 Then
With gc
.Axes(xlValue).MinimumScale = MinDD
If booMetric = True Then
MaxDD = Int(MaxDD / 100) * 100 + 100
MinDD = MaxDD - 1000
.Axes(xlValue).MaximumScale = MaxDD
.Axes(xlValue).MinimumScale = MinDD
.Axes(xlValue).MajorUnit = 200
.Axes(xlValue).MinorUnit = 40
Else
MaxDD = Int(MaxDD / 5) * 5 + 5
MinDD = MaxDD - 50
.Axes(xlValue).MaximumScale = MaxDD
.Axes(xlValue).MinimumScale = MinDD
.Axes(xlValue).MajorUnit = 10
.Axes(xlValue).MinorUnit = 2
End If
.Axes(xlValue, xlPrimary).HasTitle = True
If booMetric = True Then
.Axes(xlValue, xlPrimary).AxisTitle.Text = "Max. Dry Density, Kg/cu.m"
End If
.Axes(xlCategory, xlPrimary).HasTitle = True
If booMetric = True Then
.Axes(xlCategory, xlPrimary).AxisTitle.Text = "Percent Passing 4.75 mm Sieve"
End If
End With
End If
End Sub
So your code might be simply:
Private Sub Detail_Format(Cancel As Integer, FormatCount As Integer)
Dim MyChart As Object
Set MyChart = Me.Graph4
MyChart.Axes(xlValue).MinimumScale = something
End Sub

Microsoft Excel VBA - Run-Time Error 438

I appear to be having an error which I am struggling to figure out the reason. I have tried the help sections and also tried researching it online but have not come up with any results. I am hoping someone may be able to assist me in the matter.
Issue
I have created multiple forms for different sheets on my spreadsheet. I have made forms which can be used to hide/show select column(s) by user discretion. I have two forms which work perfectly fine, but on the third.
I get
Run-Time Error 438 "Object doesn't support this property or method"
What does this mean? The code is the exact same as the other forms. The only difference in them is that the names of the sheets are different.
I will paste the code below for the sheets. Hopefully you can distinguish which is which. I will try and do my best to explain.
Code below
Main sheet - contains button to form open form
Private Sub openUserForm_Click()
chkFormCooms.Show
End Sub
Userform
Option Explicit
Sub hideCol(C As Integer)
If Controls("CheckBox" & C) = True Then
Columns(C).Hidden = True
Else
Columns(C).Hidden = False
End If
ActiveWindow.ScrollColumn = 1
End Sub
Private Sub chkP1_Click()
If Me.chkP1.Value = True Then
Sheets("Cooms").Columns("T:W").Hidden = True
Sheets("chkCooms").chk1.Value = True
ElseIf Me.chkP1.Value = False Then
Sheets("Cooms").Columns("T:W").Hidden = False
Sheets("chkCooms").chk1.Value = False
End If
End Sub
Private Sub chkP2_Click()
If Me.chkP2.Value = True Then
Sheets("Cooms").Columns("X:AA").Hidden = True
Sheets("chkCooms").chk2.Value = True
ElseIf Me.chkP2.Value = False Then
Sheets("Cooms").Columns("X:AA").Hidden = False
Sheets("chkCooms").chk2.Value = False
End If
End Sub
Private Sub chkP3_Click()
If Me.chkP3.Value = True Then
Sheets("Cooms").Columns("AB:AE").Hidden = True
Sheets("chkCooms").chk3.Value = True
ElseIf Me.chkP3.Value = False Then
Sheets("Cooms").Columns("AB:AE").Hidden = False
Sheets("chkCooms").chk3.Value = False
End If
End Sub
Private Sub chkP4_Click()
If Me.chkP4.Value = True Then
Sheets("Cooms").Columns("AF:AI").Hidden = True
Sheets("chkCooms").chk4.Value = True
ElseIf Me.chkP4.Value = False Then
Sheets("Cooms").Columns("AF:AI").Hidden = False
Sheets("chkCooms").chk4.Value = False
End If
End Sub
Private Sub chkP5_Click()
If Me.chkP5.Value = True Then
Sheets("Cooms").Columns("AJ:AM").Hidden = True
Sheets("chkCooms").chk5.Value = True
ElseIf Me.chkP5.Value = False Then
Sheets("Cooms").Columns("AJ:AM").Hidden = False
Sheets("chkCooms").chk5.Value = False
End If
End Sub
Private Sub chkP6_Click()
If Me.chkP6.Value = True Then
Sheets("Cooms").Columns("AN:AQ").Hidden = True
Sheets("chkCooms").chk6.Value = True
ElseIf Me.chkP6.Value = False Then
Sheets("Cooms").Columns("AN:AQ").Hidden = False
Sheets("chkCooms").chk6.Value = False
End If
End Sub
Private Sub chkP7_Click()
If Me.chkP7.Value = True Then
Sheets("Cooms").Columns("AR:AU").Hidden = True
Sheets("chkCooms").chk7.Value = True
ElseIf Me.chkP7.Value = False Then
Sheets("Cooms").Columns("AR:AU").Hidden = False
Sheets("chkCooms").chk7.Value = False
End If
End Sub
Private Sub chkP8_Click()
If Me.chkP8.Value = True Then
Sheets("Coomst").Columns("AV:AY").Hidden = True
Sheets("chkCooms").chk8.Value = True
ElseIf Me.chkP8.Value = False Then
Sheets("Cooms").Columns("AV:AY").Hidden = False
Sheets("chkCooms").chk8.Value = False
End If
End Sub
Private Sub chkP9_Click()
If Me.chkP9.Value = True Then
Sheets("Cooms").Columns("AZ:BC").Hidden = True
Sheets("chkCooms").chk9.Value = True
ElseIf Me.chkP9.Value = False Then
Sheets("Cooms").Columns("AZ:BC").Hidden = False
Sheets("chkCooms").chk9.Value = False
End If
End Sub
Private Sub chkP10_Click()
If Me.chkP10.Value = True Then
Sheets("Cooms").Columns("BD:BG").Hidden = True
Sheets("chkCooms").chk10.Value = True
ElseIf Me.chkP10.Value = False Then
Sheets("Cooms").Columns("BD:BG").Hidden = False
Sheets("chkCooms").chk10.Value = False
End If
End Sub
Private Sub chkP11_Click()
If Me.chkP11.Value = True Then
Sheets("Cooms").Columns("BH:BK").Hidden = True
Sheets("chkCooms").chk11.Value = True
ElseIf Me.chkP11.Value = False Then
Sheets("Cooms").Columns("BH:BK").Hidden = False
Sheets("chkCooms").chk11.Value = False
End If
End Sub
Private Sub chkP12_Click()
If Me.chkP12.Value = True Then
Sheets("Cooms").Columns("BL:BO").Hidden = True
Sheets("chkCooms").chk12.Value = True
ElseIf Me.chkP12.Value = False Then
Sheets("Cooms").Columns("BL:BO").Hidden = False
Sheets("chkCooms").chk12.Value = False
End If
End Sub
Private Sub chkP13_Click()
If Me.chkP13.Value = True Then
Sheets("Cooms").Columns("BP:BS").Hidden = True
Sheets("chkCooms").chk13.Value = True
ElseIf Me.chkP13.Value = False Then
Sheets("Cooms").Columns("BP:BS").Hidden = False
Sheets("chkCooms").chk13.Value = False
End If
End Sub
Private Sub UserForm_Initialize()
Me.chkP1.Value = Sheets("chkCooms").chk1.Value
Me.chkP2.Value = Sheets("chkCooms").chk2.Value
Me.chkP3.Value = Sheets("chkCooms").chk3.Value
Me.chkP4.Value = Sheets("chkCooms").chk4.Value
Me.chkP5.Value = Sheets("chkCooms").chk5.Value
Me.chkP6.Value = Sheets("chkCooms").chk6.Value
Me.chkP7.Value = Sheets("chkCooms").chk7.Value
Me.chkP8.Value = Sheets("chkCooms").chk8.Value
Me.chkP9.Value = Sheets("chkCooms").chk9.Value
Me.chkP10.Value = Sheets("chkCooms").chk10.Value
Me.chkP11.Value = Sheets("chkCooms").chk11.Value
Me.chkP12.Value = Sheets("chkCooms").chk12.Value
Me.chkP13.Value = Sheets("chkCooms").chk13.Value
End Sub
I hope this all makes sense and that someone is able to assist me in this matter. If you need further explanation then please do not hesitate to ask. Thank you very much for your assistance.
Check the name of your userform its probably spelt incorrectly
For information about the error check this amazing description

Multiple timers on one Sheet

Modified [Halfway there]
Thank you YowE3K, after your comments the code has been modified but yet it is not working as it should be...
Both timers run independently and fine but only when they run separately. At the very moment when I turn both going, they start counting on every 2 seconds instead of one as it should be. I know it is maybe related to this part "Application.OnTime SchdTime + OneSec, "Sheet1.setImmediate" but I don't know how to specify the cell here. Currently they both add one second to Sheet1 when they go together.
Additionally the issue with the timers starting from 00:00:00 after reopening the document stays.
Here is the code - please note that this one is for ToggleButtons:
Dim StopTimer As Boolean
Dim SchdTime As Date
Dim Etime As Date
Dim SchdTime2 As Date
Dim Etime2 As Date
Const OneSec As Date = 1 / 86400#
Private Sub Start_Stop_1_Click()
If Start_Stop_1 = True Then
StopTimer = False
SchdTime = Now()
[K3].Value = Format(Etime, "hh:mm:ss")
Application.OnTime SchdTime + OneSec, "Sheet1.setImmediate"
Else
StopTimer = True
Beep
End If
End Sub
Private Sub Start_Stop_2_Click()
If Start_Stop_2 = True Then
StopTimer = False
SchdTime2 = Now()
[K4].Value = Format(Etime2, "hh:mm:ss")
Application.OnTime SchdTime2 + OneSec, "Sheet1.setImmediate"
Else
StopTimer = True
Beep
End If
End Sub
Sub setImmediate()
If Start_Stop_1 = True Then
[K3].Value = Format(Etime, "hh:mm:ss")
SchdTime = SchdTime + OneSec
Application.OnTime SchdTime, "Sheet1.setImmediate"
Etime = Etime + OneSec
Else: StopTimer = True
'Don't reschedule update
End If
If Start_Stop_2 = True Then
[K4].Value = Format(Etime2, "hh:mm:ss")
SchdTime2 = SchdTime2 + OneSec
Application.OnTime SchdTime2, "Sheet1.setImmediate"
Etime2 = Etime2 + OneSec
Else: StopTimer = True
'Don't reschedule update
End If
End Sub

DblClick call in VBA - close on double click without running function

Good Afternoon,
Bear with me, I am new to VBA. I have a Sub that opens a text box when its double clicked, not only do I want it to open the text box (expands it), i also want it to run a sub called EMSpull. This all works perfectly except for the fact I want to then double click to close the textbox without running EMSpull again.
Also, can someone explain "Control", especially for this situation (i didnt write the adjustheight )
Code is below
Private Sub txtEMS_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Call AdjustHeight(txtEMS, lblEMS)
Call EMSpull
End Sub
Public Sub AdjustHeight(cControl As Control, cLabel As Control)
On Error GoTo errhand
If bExpandedMode = False Then
dOldTop = cControl.Top
dOldLeft = cControl.Left
dOldWidth = cControl.Width
dOldHeight = cControl.Height
cControl.Top = lblDescription.Top + 50
cControl.Width = cControl.Width * 2
cControl.Height = 500
cControl.Left = lblResults.Left
bExpandedMode = True
Call HideAllTxt(cControl)
lblDescription.Visible = True
lblDescription.Caption = cLabel.Caption
If Len(cControl.Text) > 2 Then
cControl.CurLine = 0
End If
Else
bExpandedMode = False
Call ShowAllTxt
lblDescription.Visible = False
cControl.Top = dOldTop
cControl.Left = dOldLeft
cControl.Width = dOldWidth
cControl.Height = dOldHeight
End If
Exit Sub
errhand:
Resume Next
End Sub
I'm assuming you have a global boolean named bExpandedMode at the top of the subs? If so this should work fine:
Private Sub txtEMS_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Call AdjustHeight(txtEMS, lblEMS)
if bExpandedMode = true then Call EMSpull 'Calls it only when it expanded in AdjustHeight
End Sub
Public Sub AdjustHeight(cControl As Control, cLabel As Control)
On Error GoTo errhand
If bExpandedMode = False Then
dOldTop = cControl.Top
dOldLeft = cControl.Left
dOldWidth = cControl.Width
dOldHeight = cControl.Height
cControl.Top = lblDescription.Top + 50
cControl.Width = cControl.Width * 2
cControl.Height = 500
cControl.Left = lblResults.Left
bExpandedMode = True
Call HideAllTxt(cControl)
lblDescription.Visible = True
lblDescription.Caption = cLabel.Caption
If Len(cControl.Text) > 2 Then
cControl.CurLine = 0
End If
Else
bExpandedMode = False
Call ShowAllTxt
lblDescription.Visible = False
cControl.Top = dOldTop
cControl.Left = dOldLeft
cControl.Width = dOldWidth
cControl.Height = dOldHeight
End If
Exit Sub
errhand:
Resume Next
End Sub
Basically if that boolean exists and is used like I think it is, it just check whether the box is expanded right now or not. When it's not, the boolean is False, and AdjustHeight expands it, then turns it to true. Conversely when it is set to True, it closes it instead, and sets it to False.
So my fix just checks that same boolean and only runs it 1 way (when it just expanded)

How to pause an animation inside a loop without delay

I am having an issue with this piece of code:
Do While StopProgram = False
Do Until Count = v
Application.DoEvents()
Do While StopProgram = False
If DirectionNegative = False Then
Me.Refresh()
Count += 1
Angle += 1
RadianAngle = Angle * PlaceHolder
If Angle >= 51 Then
Angle = 49
DirectionNegative = True
End If
ElseIf DirectionNegative = True Then
Me.Refresh()
Count += 1
Angle -= 1
RadianAngle = Angle * PlaceHolder
If Angle <= -51 Then
Angle = -49
DirectionNegative = False
End If
End If
Loop
Loop
Count = 0
Loop
The problem is that when I press a button on my form, stopping the code (Using the StopProgram = False), it will continue until Count = v I want to be able to have it where I can stop it inside the loop, I have attempted to do that here but it creates an unexitable loop which ruins the program.
Better yet, use a Timer to tick at regular intervals.
http://msdn.microsoft.com/en-us/library/system.timers.timer(v=vs.110).aspx?cs-save-lang=1&cs-lang=vb#code-snippet-2
Dim WithEvents t as New System.Timers.Timer
sub t_Elapsed Handles....
'your code here. increment/decrement state variables
end sub
Simply disable the timer when you want animation to stop.
This is the wrong approach to your problem, but change:
Do While StopProgram = False
Do Until Count = v
Application.DoEvents()
Do While StopProgram = False
To:
Do While StopProgram = False
Do Until Count = v
Do While StopProgram = False
Application.DoEvents()
This should work just fine. No need for all those loops.
Public Sub Refresh()
' ...
End Sub
Public Property Get StopProgram() As Boolean
StopProgram = ' ...
End Property
Public Property Get Angle as Single
'...
Public Property Let Angle
'...
Public Property Get RadianAngle as Single
RadianAngle = Angle * PlaceHolder
End Property
Public Sub T()
Dim Step As Single
Step = 1!
Do
DoEvents
Me.Refresh
If StopProgram Then Exit Do
If Angle <= 0 Or Angle >= 50 Then
Step = -Step
End If
Count = Count + 1
Angle = Angle + Step
Loop
End Sub
You could just remove the 2 outer loops.
You will never reach the Do Until Count = v part unless StopProgram is true anyway.
You will remain inside the inner Do While StopProgram = False loop. You could remove
the inner Do While StopProgram = False loop and change
Do Until Count = v to Do Until Count = v Or StopProgram = true
btw you're setting Count = 0 when you exit the middle loop so if you need to retain the value of count when StopProgram is set to true you should remove the outer
Do While StopProgram = False loopand the Count = 0
Do Until Count = v Or StopProgram = True
Application.DoEvents()
If DirectionNegative = False Then
Me.Refresh()
Count += 1
Angle += 1
RadianAngle = Angle * PlaceHolder
If Angle >= 51 Then
Angle = 49
DirectionNegative = True
End If
ElseIf DirectionNegative = True Then
Me.Refresh()
Count += 1
Angle -= 1
RadianAngle = Angle * PlaceHolder
If Angle <= -51 Then
Angle = -49
DirectionNegative = False
End If
End If
Loop