Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
PictureBox1.Location = New Point(PictureBox1.Location.X + TextBox1.Text, PictureBox1.Location.Y) 'Timer run from left to right to the number of input
End Sub
Related
I created an "Excel VSTO document-level" project in Visual Studio. I have a pre designed "Action Pane" and a Tab Ribbon with a button in it to show my action pane.
My problem is my action pane keeps popping up (show) at least 1 time and quickly disappears before I do anything.
Here is my code so far in my ribbon:
Imports Microsoft.Office.Tools.Ribbon
Public Class Ribbon1
Dim actionsPane1 As New ActionsPaneControl1()
Private Sub Ribbon1_Load(ByVal sender As System.Object, ByVal e As RibbonUIEventArgs) Handles MyBase.Load
Globals.ThisWorkbook.ActionsPane.Clear()
Globals.ThisWorkbook.ActionsPane.Controls.Add(actionsPane1)
actionsPane1.Hide()
Globals.ThisWorkbook.Application.DisplayDocumentActionTaskPane = False
End Sub
Dim boolAP1toggle As Boolean = True
Private Sub Button1_Click(sender As Object, e As RibbonControlEventArgs) Handles Button1.Click
If boolAP1toggle = True Then
Globals.ThisWorkbook.Application.DisplayDocumentActionTaskPane = True
actionsPane1.Show()
boolAP1toggle = False
Else
Globals.ThisWorkbook.Application.DisplayDocumentActionTaskPane = False
actionsPane1.Hide()
boolAP1toggle = True
End If
End Sub
End Class
There is no need to show or hide methods of the pane class. Instead, you need to rely on the DisplayDocumentActionTaskPane property which is set to true to display the Document Actions task pane; set to false to hide the Document Actions task pane.
Private Sub Button1_Click(sender As Object, e As RibbonControlEventArgs) Handles Button1.Click
If boolAP1toggle = True Then
Globals.ThisWorkbook.Application.DisplayDocumentActionTaskPane = True
boolAP1toggle = False
Else
Globals.ThisWorkbook.Application.DisplayDocumentActionTaskPane = False
boolAP1toggle = True
End If
End Sub
I found my mistake:
Globals.ThisWorkbook.ActionsPane.Controls.Add(actionsPane1)
will inevitably show Actions Pane at the time when you try to add any form to it, so I needed to add it my Button1_Click event handler
I have created a VSTO project in Visual Studio with a Ribbon and a Form. There is a button on this form which I want when a user clicks on it, it waits for user to select a single cell from the workbook which this add-in is used in it.
I am currently at designing stage and have not much code written. Any key ideas to achieving this? Should I use Application.SendKeys method? Any other/better ideas?
Thanks
My Ribbon Code so far:
Imports Microsoft.Office.Tools.Ribbon
Public Class Ribbon1
Private Sub Ribbon1_Load(ByVal sender As System.Object, ByVal e
As RibbonUIEventArgs) Handles MyBase.Load
End Sub
Private Sub Button1_Click(sender As Object, e As
RibbonControlEventArgs) Handles Button1.Click
Dim f As New Form1
f.Show()
End Sub
End Class
My Form Code so far:
Public Class Form1
'Variables for my "Custom Vlookup Function"
Dim RHeader As Excel.Range 'Reference Header
Dim SRange As Excel.Range 'Seleceted Range
Dim ColNo As Integer 'Column number ahead
Dim xlApp As Excel.Application = Globals.ThisAddIn.Application
Dim xlWB As Excel.Workbook =
Globals.ThisAddIn.Application.ActiveWorkbook
Private Sub Button2_Click(sender As Object, e As EventArgs)
Handles Button2.Click
End Sub
End Class
Wait for the Worksheet.SelectionChange event which is fired when the selection changes on a worksheet.
Let me preface my question with the fact that I am self taught, so please provide as much detail as possible and bear with me if I need you to explain differently or multiple times.
I created a notation/email generating tool for my team using Microsoft Visual Basic 7.0. The only complaint that I received on it was that many of them are not used to hot keys so they depend on using the mouse but right click didn't work. I was able to find code that creates a pop-up for copy and paste when they use right click, and it works great on the few textboxes that are on the main form itself, however it does not work on the majority of the textboxes as they are in a Multipage.
Does anyone know how to alter the below code to work for textboxes on a Multipage? Also, before it is suggested, I did toy with the idea of moving everything out of the Multipage, however that format is the easiest as there are multiple stages and types of notes/emails that they would need to send at any time, so having tabs available for them to simply click is the most user friendly that I was able to create and that they all agreed on.
Thank you all so much in advance!
Code in the form:
Dim cBar As clsBar
Private Sub UserForm_Initialize()
On Error GoTo Whoa
Application.EnableEvents = False
Set cBar = New clsBar
cBar.Initialize Me
Letscontinue:
Application.EnableEvents = True
Exit Sub
Whoa:
MsgBox Err.Description
Resume Letscontinue
End Sub
Code in a Class Module:
Option Explicit
'Popup objects
Private cmdBar As CommandBar
Private WithEvents cmdCopyButton As CommandBarButton
Private WithEvents cmdPasteButton As CommandBarButton
'Useform to use
Private fmUserform As Object
'Control array of textbox
Private colControls As Collection
'Textbox Control
Private WithEvents tbControl As MSForms.TextBox
'Adds all the textbox in the userform to use the popup bar
Sub Initialize(ByVal UF As Object)
Dim Ctl As MSForms.Control
Dim cBar As clsBar
For Each Ctl In UF.Controls
If TypeName(Ctl) = "TextBox" Then
'Check if we have initialized the control array
If colControls Is Nothing Then
Set colControls = New Collection
Set fmUserform = UF
'Create the popup
CreateBar
End If
'Create a new instance of this class for each textbox
Set cBar = New clsBar
cBar.AssignControl Ctl, cmdBar
'Add it to the control array
colControls.Add cBar
End If
Next Ctl
End Sub
Private Sub Class_Terminate()
'Delete the commandbar when the class is destroyed
On Error Resume Next
cmdBar.Delete
End Sub
'Click event of the copy button
Private Sub cmdCopyButton_Click(ByVal Ctrl As Office.CommandBarButton, CancelDefault As Boolean)
fmUserform.ActiveControl.Copy
CancelDefault = True
End Sub
'Click event of the paste button
Private Sub cmdPasteButton_Click(ByVal Ctrl As Office.CommandBarButton, CancelDefault As Boolean)
fmUserform.ActiveControl.Paste
CancelDefault = True
End Sub
'Right click event of each textbox
Private Sub tbControl_MouseUp(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
If Button = 2 And Shift = 0 Then
'Display the popup
cmdBar.ShowPopup
End If
End Sub
Private Sub CreateBar()
Set cmdBar = Application.CommandBars.Add(, msoBarPopup, False, True)
'We’ll use the builtin Copy and Paste controls
Set cmdCopyButton = cmdBar.Controls.Add(ID:=19)
Set cmdPasteButton = cmdBar.Controls.Add(ID:=22)
End Sub
'Assigns the Textbox and the CommandBar to this instance of the class
Sub AssignControl(TB As MSForms.TextBox, Bar As CommandBar)
Set tbControl = TB
Set cmdBar = Bar
End Sub
Get ActiveControl name on a Multipage control
It's necessary to know the multipage's selected Page via a helper function (ActiveControlName) using SelectedItem property and getting the control (its name) from there. Change your button click events as follows:
Relevant button click events in class module clsBar
'Click event of the copy button
Private Sub cmdCopyButton_Click(ByVal Ctrl As Office.CommandBarButton, CancelDefault As Boolean)
Dim sACN As String
sACN = ActiveControlName(fmUserform) ' find control's name
' Debug.Print sACN & ".Copy"
fmUserform.Controls(sACN).Copy ' << instead of fmUserform.ActiveControl.Copy
CancelDefault = True
End Sub
'Click event of the paste button
Private Sub cmdPasteButton_Click(ByVal Ctrl As Office.CommandBarButton, CancelDefault As Boolean)
Dim sACN As String
sACN = ActiveControlName(fmUserform)
' Debug.Print sACN & ".Paste"
fmUserform.Controls(sACN).Paste ' << instead of fmUserform.ActiveControl.Paste
CancelDefault = True
End Sub
Helper function called by above click events
Function ActiveControlName(form As UserForm) As String
'cf Site: https://stackoverflow.com/questions/47745663/get-activecontrol-inside-multipage
'Purpose: get ActiveControl
Dim MyMultiPage As MSForms.MultiPage, myPage As MSForms.Page
If form.ActiveControl Is Nothing Then
' do nothing
ElseIf TypeName(form.ActiveControl) = "MultiPage" Then
Set MyMultiPage = form.ActiveControl
Set myPage = MyMultiPage.SelectedItem
ActiveControlName = myPage.ActiveControl.Name
Else
ActiveControlName = form.ActiveControl.Name
End If
End Function
Side note
Suggest to check for the length of selected text strings in case of empty strings to prevent from unwanted results.
I am using Windows Form Application. In that, I have a class, which consists of 5 different methods. All of them are filling private members from various sources using thread.
For that I am using following code snippet to call a method
Dim threadForMethod1 As Threading.Thread
threadForMethod1 = New Threading.Thread(AddressOf Method1)
threadForMethod1.Start()
Now I want to add on / off switch for thread. By the way, If I off the switch all the methods should execute using main thread.
What is the best way to implement it.
You can use the following Class:
Imports System.Threading
Public Class ThreadHandler
Dim t1 As New Thread(AddressOf M1)
Dim t2 As New Thread(AddressOf M2)
Public Sub M1()
Thread.Sleep(3000)
MsgBox("M1")
End Sub
Public Sub M2()
Thread.Sleep(3000)
MsgBox("M2")
End Sub
Public Sub StartAll()
If t1.ThreadState <> ThreadState.Unstarted Then
t1 = New Thread(AddressOf M1)
End If
If t2.ThreadState <> ThreadState.Unstarted Then
t2 = New Thread(AddressOf M2)
End If
t1.Start()
t2.Start()
End Sub
Public Sub StopAll()
t1.Abort()
t2.Abort()
End Sub
End Class
To Use the above Class:
Private th As New ThreadHandler()
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
th.StartAll()
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
th.StopAll()
End Sub
Creating a contextual menu within an Excel User form that applies to Images...
I am trying to write a piece of VBA code to allow me to use a contextual menu generated from right clicking an Image on an Excel User form.
Andy Pope kindly gave the world a great bit of code to add a simple context menu that applies to textboxes within an Excel User form, but not Userform.Images.
http://www.andypope.info/vba/uf_contextualmenu.htm
I have edited his code ever so slightly to prevent the contextual usage of Locked = True textboxes.
'Copyright ©2007-2014 Andy Pope
Option Explicit
Private Const mEDIT_CONTEXTMENU_NAME = "ajpiEditContextMenu"
Private Const mCUT_TAG = "CUT"
Private Const mCOPY_TAG = "COPY"
Private Const mPASTE_TAG = "PASTE"
Private m_cbrContextMenu As CommandBar
Private WithEvents m_txtTBox As MSForms.TextBox
Private WithEvents m_cbtCut As CommandBarButton
Private WithEvents m_cbtCopy As CommandBarButton
Private WithEvents m_cbtPaste As CommandBarButton
Private m_objDataObject As DataObject
Private m_objParent As Object
Private Function m_CreateEditContextMenu() As CommandBar
'
' Build Context menu controls.
'
Dim cbrTemp As CommandBar
Const CUT_MENUID = 21
Const COPY_MENUID = 19
Const PASTE_MENUID = 22
Set cbrTemp = Application.CommandBars.Add(mEDIT_CONTEXTMENU_NAME, Position:=msoBarPopup)
With cbrTemp
With .Controls.Add(msoControlButton)
.Caption = "Cu&t"
.FaceId = CUT_MENUID
.Tag = mCUT_TAG
End With
With .Controls.Add(msoControlButton)
.Caption = "&Copy"
.FaceId = COPY_MENUID
.Tag = mCOPY_TAG
End With
With .Controls.Add(msoControlButton)
.Caption = "&Paste"
.FaceId = PASTE_MENUID
.Tag = mPASTE_TAG
End With
End With
Set m_CreateEditContextMenu = cbrTemp
End Function
Private Sub m_DestroyEditContextMenu()
On Error Resume Next
Application.CommandBars(mEDIT_CONTEXTMENU_NAME).Delete
Exit Sub
End Sub
Private Function m_GetEditContextMenu() As CommandBar
On Error Resume Next
Set m_GetEditContextMenu = Application.CommandBars(mEDIT_CONTEXTMENU_NAME)
If m_GetEditContextMenu Is Nothing Then
Set m_GetEditContextMenu = m_CreateEditContextMenu
End If
Exit Function
End Function
Private Function m_ActiveTextbox() As Boolean
'
' Make sure this instance is connected to active control
' May need to drill down through container controls to
' reach ActiveControl object
'
Dim objCtl As Object
Set objCtl = m_objParent.ActiveControl
Do While UCase(TypeName(objCtl)) <> "TEXTBOX"
If UCase(TypeName(objCtl)) = "MULTIPAGE" Then
Set objCtl = objCtl.Pages(objCtl.Value).ActiveControl
Else
Set objCtl = objCtl.ActiveControl
End If
Loop
m_ActiveTextbox = (StrComp(objCtl.Name, m_txtTBox.Name, vbTextCompare) = 0)
ErrActivetextbox:
Exit Function
End Function
Public Property Set Parent(RHS As Object)
Set m_objParent = RHS
End Property
Private Sub m_UseMenu()
Dim lngIndex As Long
For lngIndex = 1 To m_cbrContextMenu.Controls.Count
Select Case m_cbrContextMenu.Controls(lngIndex).Tag
Case mCUT_TAG
Set m_cbtCut = m_cbrContextMenu.Controls(lngIndex)
Case mCOPY_TAG
Set m_cbtCopy = m_cbrContextMenu.Controls(lngIndex)
Case mPASTE_TAG
Set m_cbtPaste = m_cbrContextMenu.Controls(lngIndex)
End Select
Next
End Sub
Public Property Set TBox(RHS As MSForms.TextBox)
Set m_txtTBox = RHS
End Property
Private Sub Class_Initialize()
Set m_objDataObject = New DataObject
Set m_cbrContextMenu = m_GetEditContextMenu
If Not m_cbrContextMenu Is Nothing Then
m_UseMenu
End If
End Sub
Private Sub Class_Terminate()
Set m_objDataObject = Nothing
m_DestroyEditContextMenu
End Sub
Private Sub m_cbtCopy_Click(ByVal Ctrl As Office.CommandBarButton, CancelDefault As Boolean)
' check active textbox is this instance of CTextBox_ContextMenu
If m_ActiveTextbox() Then
With m_objDataObject
.Clear
.SetText m_txtTBox.SelText
.PutInClipboard
End With
End If
End Sub
Private Sub m_cbtCut_Click(ByVal Ctrl As Office.CommandBarButton, CancelDefault As Boolean)
If m_txtTBox.Locked = True Then
Exit Sub
End If
' check active textbox is this instance of CTextBox_ContextMenu
If m_ActiveTextbox() Then
With m_objDataObject
.Clear
.SetText m_txtTBox.SelText
.PutInClipboard
m_txtTBox.SelText = vbNullString
End With
End If
End Sub
Private Sub m_cbtPaste_Click(ByVal Ctrl As Office.CommandBarButton, CancelDefault As Boolean)
If m_txtTBox.Locked = True Then
Exit Sub
End If
' check active textbox is this instance of CTextBox_ContextMenu
On Error GoTo ErrPaste
If m_ActiveTextbox() Then
With m_objDataObject
.GetFromClipboard
m_txtTBox.SelText = .GetText
End With
End If
ErrPaste:
Exit Sub
End Sub
Private Sub m_txtTBox_MouseUp(ByVal Button As Integer, ByVal Shift As Integer, ByVal x As Single, ByVal y As Single)
If Button = 2 Then
' right click
m_cbrContextMenu.ShowPopup
End If
End Sub
What can I add to this code for the same context menu to apply with Images?
Something along the lines of...
Adding Private WithEvents m_imgImage As MSForms.Image
Private m_cbrContextMenu As CommandBar
Private WithEvents m_txtTBox As MSForms.TextBox
Private WithEvents m_imgImage As MSForms.Image
Private WithEvents m_cbtCut As CommandBarButton
Private WithEvents m_cbtCopy As CommandBarButton
Private WithEvents m_cbtPaste As CommandBarButton
Private m_objDataObject As DataObject
Private m_objParent As Object
Private Function m_CreateEditContextMenu() As CommandBar
Declaring a New Private Function
Private Function m_ActiveImage() As Boolean
'
' Make sure this instance is connected to active control
' May need to drill down through container controls to
' reach ActiveControl object
'
Dim objCtl As Object
Set objCtl = m_objParent.ActiveControl
Do While UCase(TypeName(objCtl)) <> "IMAGE"
If UCase(TypeName(objCtl)) = "MULTIPAGE" Then
Set objCtl = objCtl.Pages(objCtl.Value).ActiveControl
Else
Set objCtl = objCtl.ActiveControl
End If
Loop
m_ActiveImage = (StrComp(objCtl.Name, m_imgImage.Name, vbTextCompare) = 0)
ErrActiveimage:
Exit Function
End Function
I would need to declare a new Public Property Set
Public Property Set Img(RHS As MSForms.Image)
Set m_imgImage = RHS
End Property
Each context menu option would need altering to include the possibility of a user right clicking on an image...
Private Sub m_cbtCopy_Click(ByVal Ctrl As Office.CommandBarButton, CancelDefault As Boolean)
' check active image is this instance of CTextBox_ContextMenu
If m_ActiveTextbox() Then
With m_objDataObject
.Clear
.SetText m_txtTBox.SelText
.PutInClipboard
End With
End If
' check active image is this instance of CImage_ContextMenu
If m_ActiveImage() Then
With m_objDataObject
.Clear
'What would be the image alternative for this next line of code?
'.SetText m_imgImage.SelText
.PutInClipboard
End With
End If
End Sub
*You will note that I am only using the Copy feature of the context menu as Cutting and Pasteing from within an User form will not be required (or stable for that matter!).
And finally I would need to recreate the trigger...
Private Sub m_imgImage_MouseUp(ByVal Button As Integer, ByVal Shift As Integer, ByVal x As Single, ByVal y As Single)
If Button = 2 Then
' right click
m_cbrContextMenu.ShowPopup
End If
End Sub
It seems like an awful lot of unnecessary work, there must be an easier way.
Any help or advice is much appreciated, and once again thank you for your time.
Mr J.
If I have understood your question right, you just want to respond to all image click in one sub. This is how I do it. First create a class called ImageClickResponder (for this example) and add the following:
Option Explicit
Private Type Properties
Obj As Object
Procedure As String
CallType As VbCallType
End Type
Private this As Properties
Private WithEvents img As MSForms.Image
Public Sub Initialize(ByRef imgRef As MSForms.Image, ByRef Obj As Object, ByVal procedureName As String, ByVal CallType As VbCallType)
Set img = imgRef
With this
Set .Obj = Obj
.Procedure = procedureName
.CallType = CallType
Debug.Print imgRef.Name
End With
End Sub
Private Sub img_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
VBA.CallByName this.Obj, this.Procedure, this.CallType, Button, Shift, X, Y
End Sub
Then in your user form put this:
Option Explicit
Private micrs() As ImageClickResponder
Private Sub UserForm_Initialize()
micrs = LoadImageClickResponders(Me)
End Sub
Public Sub AllImgs_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
Debug.Print "Your context menu code here"
End Sub
Private Function LoadImageClickResponders(ByRef frm As MSForms.UserForm) As ImageClickResponder()
Dim rtnVal() As ImageClickResponder
Dim ctrl As MSForms.Control
Dim i As Long
For Each ctrl In frm.Controls
If TypeOf ctrl Is MSForms.Image Then
ReDim Preserve rtnVal(i) As ImageClickResponder
Set rtnVal(i) = New ImageClickResponder
rtnVal(i).Initialize ctrl, Me, "AllImgs_MouseDown", VbMethod
i = i + 1
End If
Next
LoadImageClickResponders = rtnVal
End Function