Selecting visio shape and running add-in for the selected shape - vb.net

I have created a visio add-in using vb.net. The add-in, when clicked, shows a form which is used to insert shape data rows for a selected shape.
Process:
Drop shape on page >> Select the shape (if not selected) >> Click the add-in button >> Windows form shows up
This works perfectly when I drop the first shape. But when I drop another shape from the same master and click the add-in button, the form does not show up.
I have this code for it:
Dim xPS as Visio.Shape
xPS = Globals.ThisAddIn.Application.ActiveWindow.Selection.PrimaryItem
If xPS Is Nothing Then
MsgBox("ERROR: " & vbCrLf & "No 'AA' shape selected. Please select an 'AA' shape and rerun the command")
Exit Sub
Else
'If a shape other than 'AA' is selected, a message box is displayed with error description.
If Left(xPS.Name, 2) <> "AA" Then
MsgBox("ERROR: " & vbCrLf & "Incorrect shape selected." & vbCrLf & "Please select 'AA' shape and rerun the command.")
Exit Sub
Else
xCT.Show() 'Shows the user form
End If
End If
I have a doubt that I am not using the correct syntax for selected shape.
xPS = Globals.ThisAddIn.Application.ActiveWindow.Selection.PrimaryItem
Can someone please tell me why the form does not show up for second shape, but it does for the first one?
Thanks for the help.
Miki

Related

MS Word VBA Macro from validation

I'm trying to do what, I think, ought to be the simplest of things, but I can't get it to work. i have an MS Word document with a number of legacy drop-down and text fields:
The first option in each drop-down is "Select ...", and if a user tabs out of one of the drop-downs without choosing something other than the first "Select ...", I want a msgbox to appear to tell them to make a selection, which works. What doesn't work, is that after the user dismisses the msgbox, I want the insertion point to return to the drop-down that they didn't select.
I understand that VBA has "timing issues", and from what I've read, one way to address these timing issues is to call the "return" macro from the validation macro. So I've written two macros:
Sub Validate()
' Dim strBookmark As String
' strBookmark = Selection.Bookmarks(1).Name
10: If (bool_debug) Then MsgBox ("NotSelected() - 10: strBookmark = " & strBookmark)
With ActiveDocument
If (strBookmark = "Locality") Then
Call Salary_Step
ElseIf (strBookmark = "Series") Then
20: If (bool_debug) Then MsgBox ("NotSelected() - 20: .FormFields(strBookmark).Name = " _
& .FormFields(strBookmark).Name)
If ((Len(.FormFields(strBookmark).Result) <> 4) Or (Not IsNumeric(.FormFields(strBookmark).Result))) Then _
MsgBox ("Please enter a 4 digit number.")
Call GoBackToPrevious(.FormFields(strBookmark).Name)
ElseIf (.FormFields(strBookmark).DropDown.Value = 1) Then
MsgBox ("Please select a " & Replace(Selection.FormFields(strBookmark).Name, "_", " ") & ".")
Call GoBackToPrevious(.FormFields(strBookmark).Name)
End If
End With
End Sub
and
Sub GoBackToPrevious(strPreviousField)
10: If (bool_debug) Then MsgBox ("GoBacktoPrevious - 10: strPreviousField = " & strPreviousField)
ActiveDocument.Bookmarks(strPreviousField).Range.Fields(1).Result.Select
End Sub
But when I tab out of any of the form fields, the insertion point jumps to the next form field and not back to the one that I just tabbed out of.
I know from the debug code that GoBackToPrevious is being passed the name of the current form field, but MS Word advances to the next field regardless.
I'd really appreciate it if someone can tell me how make MS Word return to and select the drop-down the user did not select appropriately instead of jumping to and selecting the next form field in the document.
Thank you.
P James Norris
EDIT:
Based on #TimothyRylatt comments, I have modified my macro and when they're called.
I have edited Validate as above (commenting out the Dim the strBookmark assignment, and I call it "on entry" to the next form field.
strBookmark is Dimed on the module's declaration section:
Option Explicit
Const bool_debug As Boolean = True
Const str_password As String = "###" ' I have a different password
Public strBookmark As String
and "on exit" from the "current" form field, I attempt to store the "current" bookmark name:
Sub StoreBookmark()
strBookmark = Selection.Bookmarks(1).Name
10: If (bool_debug) Then MsgBox ("StoreBookmark() - 10: strBookmark = " & strBookmark)
End Sub
which I call from the current form field "on exit".
But when I tab out of the current form field to the next form field, the insertion point doesn't go back to the "current" but instead stays in the next form field.
Anyone have any other suggestions/insights?
Thanks,
P James Norris

Form closes but the written conditions therein not implemented

I have the following two codes on a button: The (first code) aims to submit value of option button into worksheet cell:
For Each FormControl In Me.Controls
'Check only OptionButtons
If TypeName(FormControl) = "OptionButton" Then
'Check the status of the OptionButton
If FormControl.Value = True Then
'Set a variable equal to the Caption of the selected OptionButton
OptionButtonValue = FormControl.Caption
'We found the selected OptionButton so exit the loop.
Exit For
End If
End If
Next
'Store input in the worksheet
Sheets("Answer Sheet").Range("E80").Value = OptionButtonValue
To ensure an option button is selected before proceeding to next form, i have
the 'following code (second code):
Dim cnt As Integer
For Each ctl In Me.Controls
If TypeName(ctl) = "OptionButton" Then
If ctl.Value = True Then cnt = cnt + 1
End If
Next ctl
If cnt = 0 Then MsgBox "Hello " & CStr(ThisWorkbook.Sheets("AccessReg").Range("D630").Value) & ", you
have not selected an answer! Please select an answer to proceed to next question. Thank you.",
vbInformation, "Please select an answer!" Else ScoreBoards.Show
Unload Me
MY CHALLENGES
Both codes above exists in my forms i.e. questions 1, 2, 3,...respectively, but can't seem to get the second code (that, which ensures an option button is selected before next form can be opened) to work by adding 'unload me' to the end of it, yet i want the form closed before proceeding to next. Adding 'unload me', pop-up the msgbox (which tells me to select an answer) but when i clicked okay on the msgbox, it closes the form (Question1) instead of returning me to same form to ensure an answer is clicked, then proceed to next form (Question2). However, when i remove the 'unload me', things work fine i.e. the msgbox popup when selection not made, returns to same form when okay on msgbox is clicked, and opens next form when selection made.
What i really want is: i want the second code above (which ensures an option button is selected before next form can be opened) to work as programmed and each form closed before proceeding to the next form.
Thank you in advance
PS:
The concept summary is:
On a userform (Question1), select an option button and submit the value to worksheet
Ensure an option button is selected:
if selected and button clicked, the next form(being Question2) should open
if not selected and button clicked, the msgbox (which tells me to select an answer), should popup
clicking okay on the msgbox, should return me to same form (Question1) so that i can select an option and proceed.
Try adapting your second code in the next way, please:
If cnt = 0 Then MsgBox "Hello " & _
CStr(ThisWorkbook.Sheets("AccessReg").Range("D630").Value) & ", you have not selected an answer! Please select an answer to proceed to next question. Thank you.", vbInformation, "Please select an answer!"
Exit For
Else
ScoreBoards.Show
Unload Me
End if

Is there a way to programatically add Form Controls?

I'm working on a spreadsheet with a Form Control that opens a Userform used for data entry purposes. The submit button of the form fills a row of cells and adds two buttons on the last two cells of the row. It will insert as many rows as the user does and each time the two new buttons are created with their own distinct name. However, these are ActiveX controls and they are giving me compatibility problems with other Windows/Office versions once colleagues open the file and try to use it on their laptop.
This is the code I'm using to add one of the command buttons on the spreadsheet (it is essentially the same for the other button, just different variables):
Dim i As Long, Hght As Long
Dim Name As String, NName As String
i = 0
Hght = 305.25
NName = "cmdAction" & i
For Each OLEObject In ActiveSheet.OLEObjects
If Left(OLEObject.Name, 9) = "cmdAction" Then
Name = Right(OLEObject.Name, Len(OLEObject.Name) - 9)
If Name >= i Then
i = Name + 1
End If
NName = "cmdAction" & i
Hght = Hght + 27
End If
Next
Dim UpdateEntry As OLEObject, N%
Set UpdateEntry = ActiveSheet.OLEObjects.Add(ClassType:="Forms.CommandButton.1", Link:=False _
, DisplayAsIcon:=False, Left:=Selection.Offset(0, 23).Left, Top:=Selection.Offset(0, 23).Top, Width:=72, Height _
:=24)
UpdateEntry.Name = NName
UpdateEntry.Object.Caption = "Edit Entry"
With ThisWorkbook.VBProject.VBComponents(ActiveSheet.CodeName).CodeModule
N = .CountOfLines
.InsertLines N + 1, "Private Sub " & NName & "_Click()"
.InsertLines N + 2, vbTab & "Code for button goes here"
.InsertLines N + 3, vbTab & "End Sub"
End With
I was wondering if it was possible to do the same thing, but that the buttons created are form control instead of ActiveX?
The error that is displayed is Run-time error 32809: Application-defined or object-defined error. After extensive research, I've found that it happens due to the sheet getting corrupted once a different version of Windows has altered it. The only way to fix it is to create a new sheet, copying all of the contents to the new sheet, deleting the corrupted sheet and renaming the new one to the name it had previously. This works, but it is not possible to copy the ActiveX Controls, because they will be renamed and the appropriate code will not be in them, however the Form Control on the spreadsheet used to open the UserForm will work just fine, which is why I think my only solution would be to change all ActiveX to Form Control.
Would appreciate some help.
Instead of using ActiveX buttons, use Shapes and set the Shape.OnAction property to call the macro that you would normally place behind the ActiveX button. In the macro you can use Application.Caller to get the name of the shape that was clicked, thus allowing you to know which button was clicked and to branch your code accordingly.

Take the name that appears while setting an hyperlink with vba

When you want to add an hyperlink in powerpoint you can access to it for example with right click in the shape that you want and selecting "Hyperlink...". Then appears this dialog box:
As you can see there appears the slide names but those slides numbers are not the same that you can get with ActivePresentation.Slides(sliNum).Name. How can I get those names with VBA?
?ActivePresentation.Slides(75).Shapes.Title.Textframe.TextRange.Text
Should return Marketing Plan Overview in your case
This seams to be slide index and title shape text or slide name if title not found:
Function SlideTitle(ByVal Slide As Slide) As String
If Slide.Shapes.HasTitle Then
SlideTitle = Slide.SlideIndex & ". " & Slide.Shapes.Title.TextFrame.TextRange.Text
Else
SlideTitle = Slide.SlideIndex & ". " & Slide.Name
End If
End Function

How to assign a hyperlink and an onaction event to a shapes object in Excel

In microsoft excel vba, I am attempting to assign hyperlinks and/or actions to shapes I have drawn. Here is roughly what I have tried (uncomment only one line at a time)
Basically, what I want to do is allow users to get more information by clicking on a shape object. Hyperlinks are fine, but some kind of event handler which accepts parameters would be ideal. I will be creating hundreds of these shapes, and they need to link to unique places in the document.
Dim destinationHyperlinkCell as Range
set destinationHyperlinkCell = Range("10:10")
' (do some stuff here)...
With Sheet1.Shapes.AddTextbox(msoTextOrientationHorizontal, _
600, _
600, _
300, _
16)
.TextFrame.Characters.Text = "Test this thing"
.Name = destinationHyperlinkCell.Address & " group of shapes"
'.Hyperlink.Address = destinationHyperlinkCell.Address
'.Hyperlink.Range = destinationHyperlinkCell.Address
'.OnAction = "'showDebugMsg """ & .Name & """'"
End With
use "Assign Macro ..." to define a macro to each shape which fires on "Click"
You can use the same macro for each shape and use the Application.Caller property to get the name of the shape which fired the macro. Then you have all the ingredients to write an intelligent handler - like a (hidden) Excel table that resolves shape name into an URL, text or whatever
Sub Shape_Click()
MsgBox "Co-Cooo! from" & Application.Caller
End Sub
Hope that helps
Good luck - MikeD