Macro in word to add text box with file path - macos

I'm totally new to this. I want to create a macro that add to my document the file path (at the time when the macro runs) into a text box that goes at the end of the document. I use Word 2016 for Mac.
I've found code on other threads that helped me to understand how to create the text box and work on its position in the document but I'm not able to add the file path code.
This is what I came up with so far:
Sub percorsofile2()
Dim Box As Shape
Set Box = ActiveDocument.Shapes.AddTextbox( _
Orientation:=msoTextOrientationHorizontal, _
Left:=50, Top:=50, Width:=100, Height:=15)
Box.TextFrame.TextRange: Selection.Fields.Add Range:=Selection.Range,
Type:=wdFieldEmpty, Text:="FILENAME \p "

You're very close! Just one little change...
The Selection is not in the TextBox, which is why the field code is not getting inserted in the right place. While you could first select the TextBox range, it's usually better to work directly with a Range object, rather than a selection.
My sample code declares a Range object, then sets it to the Box.TextFrame.TextRange. The field code can then be inserted at this position.
Sub percorsofile2()
Dim Box As Shape
Dim rng As Word.Range
Set Box = ActiveDocument.shapes.AddTextbox( _
Orientation:=msoTextOrientationHorizontal, _
Left:=50, Top:=50, width:=100, height:=15)
Set rng = Box.TextFrame.TextRange
rng.Fields.Add Range:=rng, Type:=wdFieldEmpty, Text:="FILENAME \p "
End Sub

Related

Proper Casing in VB6

I am doing a quiz game in VB6. I need the textbox to automatically capialize the first letter but this code
Private Sub Anstxt_Change()
Anstxt.Text = StrConv(Anstxt.Text, vbProperCase)
End Sub
causes the word to invert. So instead of "Trees" it turns into "Seert"
How do I change this?
Pay attention to where the cursor is positioned in the textbox when the event Change occurs: its at the start of the textbox. Add a Debug.Print statement to see what's going on while you type:
Private Sub Anstxt_Change()
Debug.Print StrConv(Anstxt.Text, vbProperCase)
Anstxt.Text = StrConv(Anstxt.Text, vbProperCase)
End Sub
The output looks like
T
T
Rt
Rt
Ert
Ert
Eert
Eert
Seert
Seert
Two things to notice here: the Change event is triggered twice: once from typing and once from changing the value of the textbox within the Change event. That gives you an idea that manipulating the text of a textbox in its Change event isn't a good idea. I suggest to put this code in the LostFocus event instead.
The second thing to notice is that as the cursor is always at the start of the textbox, the letters you type are inserted there in front of the existing letters. So after you change the .Text property of the textbox, you should position the cursor at the end of the textbox with the .SelStart method:
Anstxt.SelStart = Len(Anstxt.Text)
e.g.
Private Sub Anstxt_Change()
Anstxt.Text = StrConv(Anstxt.Text, vbProperCase)
Anstxt.SelStart = Len(Anstxt.Text)
End Sub

How to get hidden/private UI element from UIAutomation, I can see it in Spy++ but can't get to it in code, only it's parents and siblings

I'm trying to use System.Windows.Automation to get to a UI element in VLC media player (specifically the status box in the left-most corner that shows the filename of the video currently being played). I can get the parent element and a sibling element but in Spy++ all of the elements that have a dimmed icon next to them I cannot reach in code... I'm assuming that dimmed icon means they are private or hidden or something like that. Here is an image showing what I mean:
Notice that I have a reference to the parent with the handle 0x30826, and I do a FindAll()* from that and end up with only one result, a reference to the child with the handle 0x30858. You can see in Spy++ there are 5 children of 0x30826, but only one of them, the one that I get when I do FindAll, has a fully black icon, the others have a gray icon and I cannot get to them. Notice also that the one I want is 0x20908 and it has a grey icon...
How can I get to this in code?
*This is the code I'm using to try to get all the children of 0x30826:
Dim aeDesktop As AutomationElement
Dim aeVLC As AutomationElement
Dim c As AutomationElementCollection
Dim cd As New AndCondition(New PropertyCondition(AutomationElement.IsEnabledProperty, True), New PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.StatusBar))
aeVLC = aeDesktop.FindFirst(TreeScope.Children, New PropertyCondition(AutomationElement.NameProperty, "got s01e01.avi - VLC media player"))
c = aeVLC.FindAll(TreeScope.Children, cd)
c = c(0).FindAll(TreeScope.Children, Condition.TrueCondition)
The first FindAll() gives me only 0x30826, which is fine because that's what I want, but the second FindAll, with no conditions specified, gives only 0x30858 when I can see that plus 4 others in Spy++, including the one that I want.
You are really handicapping your efforts by using Spy++ instead of the Inspect Program. Using Inspect, you can easily see that the target element is a text element parented to a status bar element that is parented to the main window element.
Using that information, getting a reference to the target text element is straight forward. Start by getting the main window, then its status bar and finally the first text element of the status bar.
' find the VLC process
Dim targets As Process() = Process.GetProcessesByName("vlc")
If targets.Length > 0 Then
' assume its the 1st process
Dim vlcMainWindowHandle As IntPtr = targets(0).MainWindowHandle
' release all processes obtained
For Each p As Process In targets
p.Dispose()
Next
' use vlcMainWindowHandle to get application window element
Dim vlcMain As AutomationElement = AutomationElement.FromHandle(vlcMainWindowHandle)
' get the statusbar
Dim getStatusBarCondition As Condition = New PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.StatusBar)
Dim statusBar As AutomationElement = vlcMain.FindFirst(TreeScope.Children, getStatusBarCondition)
' get the 1st textbox in the statusbar
Dim getTextBoxCondition As Condition = New PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Text)
Dim targetTextBox As AutomationElement = statusBar.FindFirst(TreeScope.Children, getTextBoxCondition)
' normally you use either a TextPattern.Pattern or ValuePattern.Pattern
' to obtain the text, but this textbox exposes neither and it uses the
' the Name property for the text.
Dim textYouWant As String = targetTextBox.Current.Name
End If

Using VBA Macro To open Link to picture

My goal of this program is to open a picture in a folder by selecting a cells value in the active row which im using the line to do.
picture = Cells(ActiveRow, 6).Value
I am getting a Run time error '1004' Application-defined or object defined error
Here is my full code
Sub Picture_Click()
Sheets("Master").Unprotect Password:="Conti1"
Sheets("Records").Unprotect Password:="Conti1"
Dim picture As String
Dim ActiveRow As Long
Worksheets("Master").Activate
ActiveRow = Rows(ActiveCell.Row).Select
picture = Cells(ActiveRow, 6).Value
ChDir"P:\926_TM\03_LocalExchange\Tracking_and_Labeling\LabEquipment\pictures"
Workbooks.Open picture
End Sub
I am trying to use the value from the selected cell to be the name of the picture file in the selected folder, the picture I would like to open.
also I am getting a value of -1 for ActiveRow
Any help would be great!
You can't open a picture with the Workbooks.Open method, as that method is exclusively for opening workbooks.
One option is to use a Shell command to open the picture. In this example, I will open a picture located on the the Pictures folder named Test.png
Private Sub OpenPic()
Shell "mspaint.exe C:\Users\USERNAME\Pictures\Test.png"
End Sub
This will open the picture in paint.
Adapting this method to your code:
Sub Picture_Click()
Sheets("Master").Unprotect Password:="Conti1"
Sheets("Records").Unprotect Password:="Conti1"
Dim picture As String
Dim ActiveRow As Long
Worksheets("Master").Activate
ActiveRow = ActiveCell.Row
picture = Cells(ActiveRow, 6).Value
Shell "mspaint.exe P:\926_TM\03_LocalExchange\Tracking_and_Labeling\LabEquipment\pictures\" & picture
End Sub
This assumes that the value in Activerow, 6 includes the file extension.
As an aside: I would add that you don't need to define ActiveRow at all and could just use it as-is.
So this:
ActiveRow = ActiveCell.Row
picture = Cells(ActiveRow, 6).Value
Can be rewritten as:
picture = Cells(ActiveCell.Row, 6).Value
And you can omit the ActiveRow variable altogether.
ActiveRow is a Long, so you cannot select a row and say that is a number. You would simply write
ActiveRow = ActiveCell.Row
In the immediate window, if you write ?Rows(ActiveCell.Row).Select, it will return a Boolean Value, not a number.
Also to open a file you should use the FollowHyperlink method:
from msdn:
ActiveWorkbook.FollowHyperlink Address:="http://example.microsoft.com"
Your link would replace the one in the example of course.
picture = "P:\926_TM\03_LocalExchange\Tracking_and_Labeling\LabEquipment\pictures\" & Cells(ActiveRow, 6).Value
ActiveWorkbook.FollowHyperlink Address:=picture
This answer will help you to open in default photo viewer.
I tried,
Sub image_opener()
Dim photo_path As String
photo_path = Worksheets("Sheet1").Range(Selection.Address).Value
PID = Shell(photo_path, vbNormalFocus)
End Sub
but the above code didn't work for me. I think the McAfee in my PC is preventing the excel from running that shell command.
So, I created a openImg.bat file containing
%1
%1 basically takes the input from the user.
Normally we can open image using this openImg.bat by,
openImg.bat path_of_image/image.jpg
So, I edited the VBA accordingly
Sub image_opener()
Dim photo_path As String
photo_path = Worksheets("Sheet1").Range(Selection.Address).Value
PID = Shell("bat_file_path\openImg.bat " & photo_path, vbNormalFocus)
End Sub
photo_path = "image_path/image.jpg" . Finally I setup a shortcut key for the macro from Developer>Macros>Options>Shortcut Key .
The above worked for me.

Change view of specific split view

I'm looking to have my excel sheet with a split in it (vertically) ensuring a set of controls stay on the left of the screen for easy access. Currently Im using this code to select and move to a cell, based on a list of headings I have in the A column.
Option Explicit
Dim trimProcess() As String
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim i As Integer
If Not Intersect(ActiveCell, Range("A6:A1000")) Is Nothing Then
If ActiveCell.Value <> "" Then
For i = 0 To UBound(trimProcess)
If ActiveCell.Value = trimProcess(i) Then
Cells(4, 4 * (i + 1)).Select
Cells(4, 4 * (i + 1)).Activate
End If
Next
End If
End If
End Sub
This works fine for what I need, but it only works in the active split view IE if I click a cell in A in the left split, it moves the left split view. I want it so that the changes only the right view, but cant find the code to do so. Is this possible?

How to call a visio macro from a stencil

i have written some Macros for Visio. Now I copied these to a Stencil called Macros.vss
How can I call my Macros now?
It all depends on what the macros do and how you'd like to call them. I'm going to assume they're simply macros that will execute something within the active Visio page.
By default in Visio VBA, any public subs with no arguments get added to the Visio Tools->Macros menu, in a folder named by the document holding the macros (in this case Macros) and then separated into folders by module name. If you're the only person using the macros then you probably don't need to do anything else.
However, since you put them in a vss file I'll assume you'd like to distribute them to other people.
There's something funny (and by funny I mean irritating) about Visio and how toolbars and buttons work, when added programmatically. Unfortunately, when you create a toolbar using the UIObject and Toolbar and ToolbarItem classes, Visio is going to assume the code you're calling resides in the active drawing, and cannot be in a stencil. So I can give you a little guidance on using those classes, but basically it consists of distributing a .vst template along with your .vss files, with just a single required sub in the .vst file.
So, instead of using a custom toolbar, you can attach code to shape masters in your .vss file that execute the code when they get dropped on a drawing document (using CALLTHIS and the EventDrop event in the shapesheet). With this method I just have a sub that gets called using callthis that takes a shape object as an argument, executes some code, then deletes the shape (if I don't want it around anymore).
And lastly, you can manipulate the Visio UI programmatically to add a toolbar and buttons for your macros. Below is some sample code, basically the way I do it with a solution I developed. As I mentioned above, the most important part of using this method is to have a document template (.vst) that holds a sub (with the below code it must be named RunStencilMacro) that takes a string as an argument. This string should be the "DocumentName.ModuleName.SubName". This sub must take the DocumentName out of the string, and get a Document object handle to that document. Then it must do ExecuteLine on that document with the ModuleName.SubName portion. You'll have to step through the code and figure some things out, but once you get the hang of what's going on it should make sense.
I'm not sure of any other ways to execute the macros interactively with VBA. I think exe and COM addons may not have this issue with toolbars...
Private Sub ExampleUI()
Dim UI As Visio.UIObject
Dim ToolbarSet As Visio.ToolbarSet
Dim Toolbars As Visio.Toolbars
Dim Toolbar As Visio.Toolbar
Dim ToolbarItems As Visio.ToolbarItems
Dim ToolbarItem As Visio.ToolbarItem
Dim TotalToolBars As Integer
Dim Toolbarpos As Integer
Const ToolbarName = "My Toolbar"
' Get the UIObject object for the toolbars.
If Visio.Application.CustomToolbars Is Nothing Then
If Visio.ActiveDocument.CustomToolbars Is Nothing Then
Set UI = Visio.Application.BuiltInToolbars(0)
Else
Set UI = Visio.ActiveDocument.CustomToolbars
End If
Else
Set UI = Visio.Application.CustomToolbars
End If
Set ToolbarSet = UI.ToolbarSets.ItemAtID(visUIObjSetDrawing)
' Delete toolbar if it exists already
TotalToolBars = ToolbarSet.Toolbars.Count
For i = 1 To TotalToolBars
Set Toolbar = ToolbarSet.Toolbars.Item(i - 1)
If Toolbar.Caption = ToolbarName Then
Toolbar.Visible = False
Toolbar.Delete
Exit For
End If
Next
' create toolbar
Set Toolbar = ToolbarSet.Toolbars.Add
Toolbar.Caption = ToolbarName
Dim IconPos As Long ' counter to determine where to put a button in the toolbar
IconPos = IconPos + 1
Dim IconFunction As String
IconFunction = """Macros.Module1.SubName"""
Set ToolbarItem = Toolbar.ToolbarItems.AddAt(IconPos)
With ToolbarItem
.AddOnName = "RunStencilMacro """ & IconFunction & """"
.Caption = "Button 1"
.CntrlType = Visio.visCtrlTypeBUTTON
.Enabled = True
.state = Visio.visButtonUp
.Style = Visio.visButtonIcon
.Visible = True
.IconFileName ("16x16IconFullFilePath.ico")
End With
' Now establish the position of this toolbar
With Toolbar
.Position = visBarTop 'Top overall docking area
.Left = 0 'Puts it x pixels from the left
.RowIndex = 13
.Protection = visBarNoCustomize
Toolbar.Enabled = True
.Visible = True
End With
Visio.Application.SetCustomToolbars UI
Visio.ActiveDocument.SetCustomToolbars UI
End Sub

Resources