Track which hyperlink called a slide - vba

A quiz was created using PowerPoint. Each question has multiple-choice answers. For each answer, a hyperlink was created to either send it to a slide indicating a correct answer (only one) or a slide indicating an incorrect answer (all the others). It needs to capture which answer the user clicked. The correct one is easy because only one answer will open the correct slide, but all the incorrect answers go to the same slide.
Is there a way to capture what object/hyperlink ID/Name, etc. that "called" a slide? I want to avoid writing separate Events for each hyperlink. Is there a way to capture it in the Application Event?
I have the following code.
Class Code:
Public WithEvents PPTEvent As Application
Private Sub PPTEvent_SlideShowNextSlide(ByVal Wn As SlideShowWindow)
MsgBox ActivePresentation.Slides.Item(1).SlideNumber
End Sub

PowerPoint supports action settings to run a macro. Define the macro as follows:
Sub ClickMe(Shp As Shape)
MsgBox Shp.Name
End Sub
Now, assign the action setting to run this macro and see how the shape reference is passed along. You can use that to avoid using events altogether. Drive the quiz using code.

Related

How to create a macro to jump to the end of a document in Libre Office Basic

Each time I open my Libre Office document to add updates, I have to press CTRL+END to jump to the bottom of the document. I thought of adding a button to jump-to-the-bottom, but the Basic it uses is not VBA, so I'm in a pickle. Can anyone give me a sub?
As an after-thought; can I add an instruction to the document-startup?? to cursor-jump-to-the-bottom of the file? Please forgive my pants naming conventions, I'm still green!
I tried the offline help to no avail. Next I tried Google but could not find an exact sub to match. I then subscribed to the TheDocumentFoundation and was presented with an SO-like Q&A forum. The discobot did not help!
I also tried recording a macro which does work ok. The sub code is:
sub Main
rem define variables
dim document as object
dim dispatcher as object
rem get access to the document
document = ThisComponent.CurrentController.Frame
dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")
dispatcher.executeDispatch(document, ".uno:GoToEndOfDoc", "", 0, Array())
end sub
I cannot however add the commands to the document.init or startup.
In fact, the macro for moving the cursor to the end of the document is a little easier to write. Each document has a controller. The text document controller has a "view cursor". You can control this cursor using its methods, in this case you need the .gotoEnd() method.
So the code can be like this: "if this document is a text document, then get its controller, take the cursor from the controller, make the cursor jump to the end of the text"
Sub jumpToEnd(Optional oEvent As Variant)
If ThisComponent.SupportsService("com.sun.star.text.TextDocument") Then
ThisComponent.getCurrentController().getViewCursor().gotoEnd(False)
EndIf
End Sub
The best place for this macro is some module in the Standard library under "My Macros" - this library will be loaded immediately after starting the office and macros will be available for execution at any time. (If you want to run this macro only for one document, then you can place it in the Standard library of this document)
To run the macro automatically, use the Tools - Customize - Events tab
This is where you specify whether the macro should be executed when you open one specific document or when you open any document.
Now that you know how to do this, you will probably agree that pressing Ctrl+End is much easier.

Using VBA to allow a checkbox to hide/show content in Microsoft Word

I've gone through a number of tutorials and instructional videos trying to achieve my intended result of simply allowing a checkbox in my form to hide content when selected, or re-show it when being de-selected, but nothing seems to be working.
Currently, I've created a bookmark for the content I want hidden, and try to call his this in VBA with the following statement - which a number of resources indicated as the solution:
Private Sub CheckBox1_Click()
ActiveDocument.Bookmarks("bookmark").Range.Font.Hidden = CheckBox1.Value
End Sub
But despite doing this, selecting the checkbox has no affect on the content.
Is there something additional I'm missing (I'm using Microsoft Word 2013).
Your code worked fine when I tested it, but I ran into a few issues since I've never messed with userforms/checkboxs in Word VBA and I suspect you may have the same.
For instance, the first thing I did was create Insert --> Module. This is incorrect. What you want to do is Insert --> Userform then drag a checkbox over from the ToolBox
https://smallbusiness.chron.com/use-check-boxes-word-54673.html
Then double click the checkbox to bring up the "module" it would run, notice there is no module in the side pane! Edit the module, then go back to the userform and press F5. You should be presented with a checkbox that will hide/unhide your text.
Here is my module:
Public Sub CheckBox1_Click()
ActiveDocument.Bookmarks("bookmark").Range.Font.Hidden = CheckBox1.Value
End Sub
Here is an image:
Note: I didn't test how to insert the checkbox into the word doc, I'll leave you some of the learning!
Update:
This sub will make the CheckBox appear when run, but I'm not sure the logic you would use to call it, perhaps an event like opening of document?
Sub Loadform()
Load UserForm1
UserForm1.Show
End Sub
This could be called via a keyboard shortcut or event, but this will cause a "pop-up window". If you want an inform checkbox you may need to look into using this Legacy Form/Checkbox. I was following the URL from above but I think it's dated.
Update:
You could also add this easily to a toolbar, but that isn't likely what you want. I found the best way is to use a "field code" see --> https://word.tips.net/T001571_Assigning_a_Macro_to_a_Button_in_Your_Text.html
I was able to get this to work by pressing CTRL + F9 then typing { MacroButton Loadform ClickMe} then clicking this text. This may be the best bet as using an image seems not to be a great idea.. (https://answers.microsoft.com/en-us/msoffice/forum/all/using-graphic-with-macrobutton/a9c1ef3b-cf1f-48ba-92a8-c44bffcdc131) & (http://www.addbalance.com/usersguide/parts/macrobutton_fields.htm#Different_behavior)
Gif Example:

Auto-updatable links

Is there a way to apply "auto-updatable" style for hyperlink?
I believe, this question is not trivial.
When you normally click on hyperlink, it will change it's color to violet. Next, if you save, close, and then reopen the document, the link will be updated back to blue. This is default behaviour of Word, and there is no need to use any macros for it.
I'm trying to replicate this behaviour with VBA. Here is the code:
Sub Test1()
Selection.Range.Hyperlinks(1).Range.Fields(1).Result.Style = Word.WdBuiltinStyle.wdStyleHyperlinkFollowed
End Sub
To make it work, simply put caret into the link, run macro, and see the results:
This works fine, except such visited links will not be auto-updated after you save, close, and then reopen the document. See the difference in the picture below. The link "Google" was opened normally, using the mouse Ctrl-click; the link "StackOverflow" was opened using the macro:
As I already said, I want to make my VBA-opened links (StackOverflow) auto-updatable as well (as Google).
Yes, I understand, there is a workaround - simply create another macro, which will be started every time the document opened and change all violet hyperlinks back to blue. However, this is just workaround, and I don't like it. Using it, we use conversion from "permanent violet" to "permanent blue", instead of using "temporary violet" (that's mean, auto-updatable without any additional efforts).
Hope everything is clear. Thanks in advance.
Update (was added after several answers were already posted).
Yes, I understand, this will work:
Sub Test1()
On Error Resume Next 'To avoid an error in case if the link isn't reachable
Selection.Hyperlinks(1).Follow
End Sub
But I want just simulate following, without really opening the link in the browser. That's why, I can't use Selection.Hyperlinks(1).Follow.
you need to remove the line, the link will change once followed and change back once the doc is reopened.
Selection.Range.Hyperlinks(1).Range.Fields(1).Result.Style = Word.WdBuiltinStyle.wdStyleHyperlinkFollowed
this does it for me
Sub resetHyperlinks()
Dim hLink As Hyperlink
For Each hLink In ActiveDocument.Hyperlinks
hLink.Address = hLink.Address ' this works
' hLink.ScreenTip = hLink.ScreenTip ' this works also
Next hLink
End Sub
You don't need to change the style with code to make the link purple. Just use the Follow method. This will click the link and turn it purple and then it will be reset to blue upon opening the document again.
Sub Test1()
Selection.Range.Hyperlinks(1).Follow
End Sub
You can reset link styles with VBA code that runs at startup, i.e. is a part of Document_Open() routine in ThisDocument VBA module.
The Hyperlink class doesn't have any .Visited property or anything relevant (i.e. you cannot even see if it was visited), so there's no other way beside .Follow() that also opens the link as it should.
You're basically trying to falsify the information that the document provides about its state: make a link appear visited when it actually wasn't.
The fact that the class doesn't even provide a property means that Word's designers do not consider the visited status a part of the editor's functionality (i.e. it effectively doesn't exist as far as the program's job is concerned).
This evidence suggests that Word doesn't, and is not designed to, have any specialized facility to switch link status other than .Follow(). Which means, any way that you find that happens to have the desired effect in bound to be what you're calling a "workaround".
The "temporary" color of a followed hyperlink is an embedded (and not directly accessible) feature of the built-in Hyperlink character style. It is not exposed through the normal UI's Style tools, nor through the object model.
You can readily compare all formatting between two selections using the Reveal Formatting pane (Shift+F1) in the document window in Word.
If you compare a normally followed hyperlink with a hyperlink affected by your snippet, you'll see that the followed hyperlink still has the Hyperlink style, while your simulated follow has changed the style of the second hyperlink.
If you compare a never-followed hyperlink and a normally followed hyperink, Word identifies their formatting as exactly the same. Word does not acknowledge that any aspect of formatting (style, font color, etc.) has changed.
It seems likely that the Word.WdBuiltinStyle.wdStyleHyperlinkFollowed you are using exists explicitly to address this gap (which is somewhat disappointing).
I recommend using your existing approach, and then reverting the style in a procedure triggered by the Before Save and Before Close events of the document. Using those events will prevent the followed style from saving at all, and so avoid issues caused by someone opening the document without enabling macros.
Option Explicit
Sub test()
Dim HL As Hyperlink
For Each HL In Sheet1.Hyperlinks
HL.Range.Style.Font.Color = vbBlue
Next
End Sub
Can't you simply make it any colour you want without invoking it. As others have stated above whatever you you I think will be a work around as it's not an intended function.

handle Powerpoint shape click event in c# code

I want to handle a powerpoint shape's click event in slide show mode.
I want to write event handler in a C# vsto addin.
Please help me I am stuck in this as in google search I am not able to find any answer to this.
In normal view, you could respond to the Selection Changed event to determine whether a particular shape had been clicked, but you can't select anything in slide show view.
But you can assign an action setting to a shape, make it a Run Macro action and have it call a bit of VBA code within the presentation, for example:
Sub AndThenHeClickedMe(oSh as Shape)
MsgBox "You clicked " & oSh.Name
End Sub
Your VBA code could possibly call a DLL that you provide as well, so you don't need to write all of the following code in VBA if you don't wish to.

Powerpoint Event handling - Prevent New Presentation

I am creating a Powerpoint Add-in. I would like to restrict user from either:
Create New Presentation
Open an existing Presentation
I have used this tutorial/overview to trap the NewPresentation and PresentationOpen events. I would like to close any presentation initialized through these events before the user can interact with it. When I try to close it using .Close method, I receive an error (screenshot below).
In my class module, I have the following to trap the NewPresentation event. This works fine, I receive the message box and Pres is a valid Presentation object that can be passed to the CloseNewPres routine.
Private Sub PPTEvent_NewPresentation(ByVal Pres As Presentation)
MsgBox "You cannot use this Charting tool with multiple presentations.", vbInformation
CloseNewPres Pres
End Sub
In a standard module, I have the CloseNewPres routine, which I expect to close the "New" presentation:
Sub CloseNewPres(Pres As Presentation)
Application.Presentations(Pres.Name).Close
'Pres.Close '<~~ This also fails.'
End Sub
I receive the following error.
Any thoughts on why this is happening? Or what I can do to close these presentations?
In my opinion you need to use another event which is quite similar to one you used:
Private Sub PPApp_AfterNewPresentation(ByVal Pres As Presentation)
If I set Pres.Close within proposed one it really closes new created presentation.
The best explanation I have (and this is my own interpretation) is that it's barking because you're trying to remove an object (the presentation) while the event handler is dealing with it. Kind of asking the event handler to pull the rug out from under its own feet.
By the way, it won't work to call another routine from within the event handler and have IT do the deed because the event handler's still active.
One way around this:
Have the event handler load a form modelessly.
When you do that, the remaining code in the event handler runs to completion.
The form's initialization code can close the presentation if your conditions are met.
The form needn't ever become visible for this to work.
Yep. Seems bizarre. But it works.
In C#.Net you can do by this way,
using pp = Microsoft.Office.Interop.PowerPoint;
pp.Application app = Globals.ThisAddIn.Application;
app.AfterNewPresentation += Event_PresNew;
public void Event_PresNew(pp.Presentation pres)
{
//.....your code here....
}
Also you can see the list of all the events you can use in powerpoint here below,
https://learn.microsoft.com/en-us/office/vba/api/powerpoint.application.newpresentation(even)