Setting shape position to book layout in vba - vba

I want to use a word macro to set the position of the shapes in the document to book layout (see screenshot). But I can't find any reference which member I need to set for this (probably because my word is in german and this is called differently in the macro).
Can anyone tell me how to set the horizontal layout of a shape to book layout in vba?
[update] The following did the trick:
Shape.Left = -999994
Shape.LeftRelative = -999999
Shape.RelativeHorizontalPosition = wdRelativeHorizontalPositionMargin

In the most recent versions of Word the macro recorder gives no help for graphical objects. The next best thing you can do is to look at the properties available for the object in the Object Browser (F2).
If a graphical object has "text wrap" formatting then it belongs to the Shapes collection, so the list you need to look up is that of the Shape object.
In there you'll find the property RelativeHorizontalPosition, which takes a member of the WdRelativeHorizontalPosition enumeration. Looking at that list there are a number of options, none of which has "book" in it.
So the next step is to insert and format a Shape with the desired positioning. Then in the Immediate Window (Ctrl+G) you can type:
?ActiveDocument.Shapes(1).RelativeHorizontalPosition
Then press Enter. This will print a number that corresponds to the list of Enumeration members.
You can also test the effect of the various members by assigning them in the Immediate Window:
ActiveDocument.Shapes(1).RelativeHorizontalPosition = wdRelativeHorizontalPositionOuterMarginArea
Press Enter.
What you'll see is that there is not an enumeration member for every option in the dialog box. And that various positioning options in the dialog box correspond to a single enumeration member.
For your specific question, wdRelativeHorizontalPositionInnerMarginArea corresponds to the dialog box option you indicate.
ActiveDocument.Shapes(1).RelativeHorizontalPosition = wdRelativeHorizontalPositionInnerMarginArea
Besides the above, you need to use the LeftRelative and Left properties, as well. Take a look at those settings in the Immediate Window after using the dialog box and play with them, putting the image on odd/even pages.If it disappears - it's off visible portion of the page, which you can see in Reading View. In a nutshell, you need the NEGATIVE numbers to lock the image to the margin or page side. Positive numbers position it absolutely.

Related

How do I save selected objects as a variable and recall that selection in PowerPoint using VBA?

I am trying to build a macro that allows the user to select a few ojbects in PowerPoint, name that selection, then at a later stage pick a name to reselect those objects.
I am stuck at saving the current selection as a variable, and saving that variable as part of the PPT, so that when a user opens the file again those selections are still availible.
I've tried declaring a variable of the Selection type, and setting its value to the active selection. But this gives an error.
You can't save a selection as such, but you can tag the selected shapes when the user opts to save the current selection, then when the user chooses to re-select that particular selection, look at each shape on the slide and if it has the appropriate tag, add it to the selection.
I have a free add-in that does pretty much what you're after:
https://pptools.com/free/FAQ00003-Selection-Manager.htm

PowerPoint VBA add shape event/ add shape with tag value

i'am currently trying to add a small function to PowerPoint using VBA, my goal is to create a gadget that works kind of like Photoshop graphics layer.
My plan is to add a layer name Tag on each shape that is drawn by user, so later I can parse through every item by loop and preform lock/unlock, show/hide shapes based on it's tag value, such as:
Sub add_shape_with_layer_tag()
Set islide = ActivePresentation.Slides(1)
Set ishape = islide.Shapes.AddShape(msoShapeRectangle, 5, 5, 80, 60)
ishape.Tags.Add "Layer", "1"
End Sub
Sub show_hide_layer_one_shapes()
Dim active_slide As Slide
Set active_slide = ActiveWindow.View.Slide
For Each ishape In active_slide.Shapes
If ishape.Tags("Layer") = "1" Then
ishape.Visible = Not (ishape.Visible)
End If
Next ishape
End Sub
However, I couldn't found a way to achieve this, so I would like to ask whether there's a method that provides following functions?
override add shape function so I can sneak tag value in to shape every time user drawn a shape
catch add shape event (if this thing did exist) so i can add tag to the last added item
a way to set a default tag value to shape, just like setting default shape color/line width
or is there any better options that is also viable?
thanks.
20200728
To John, thanks for the advice, I did found some interesting event that might be helpful for some of my other projects, however I couldn't found events that able to trigger after custom function while shape is added.
To Steve, my plan is to add a modeless userform with list UI that manage layers, the shape tag and shape fill texture/color will be determined based on what list item that currently selected.
As to saving settings, I'll use VBComponents.CodeModule to dump existing settings in userforms to a VBA module and store as text, so in theory I should able to make this function self contained in one file.
Not totally an answer, sorry SO, but comments don't allow enough scope for this. So ...
To Steve, my plan is to add a modeless userform with list UI that manage layers, the shape tag and shape fill texture/color will be determined based on what list item that currently selected.
Ah, so you're creating your own "pseudo-layers". That wasn't clear. Thanks for the add'l info. As it happens, I have a selection manager add-in that works very similarly to what you're proposing.
To John, thanks for the advice, I did found some interesting event that might be helpful for some of my other projects, however I couldn't found events that able to trigger after custom function while shape is added.
The SelectionChange event should get you there. When it fires, you'll need to check first to see if the current selection is a shape or something else. If a shape, check to see if its .Index = current slide's .Shapes.Count and also to see if you've already tagged it. If no tag AND if it's the correct index, it'll be a newly added shape. If you're tagging ALL shapes, you may only need to check to see if the .Tag(name) is blank.
As to saving settings, I'll use VBComponents.CodeModule to dump existing settings in userforms to a VBA module and store as text, so in theory I should able to make this function self contained in one file.
Why not save any needed slide or presentation level info as further slide- or presentation-level tags? PPT can absorb quite a lot of info as tags w/o getting cranky.

Select all text without ActiveX buttons

I am trying to build a template that has ActiveX buttons for calling Sub procedures. At some point, I have to select the text and convert it to a table.
So, I have to find a way to select the text, without selecting the ActiveX controls.
I've figured there would be two approaches:
write a code that selects the text without objects (I only have
ActiveX objects);
change the objects property in a way that they don't get
selected using Selection.WholeStory or similar code.
I've tried the following methods, without success:
using Selection.WholeStory - it selects all text, including the ActiveX controls
wraping the objects Square, not in line with the text, and positioning them outside the printing area - the objects still get selected
putting the objects in the header - in this way, the buttons cannot be used/clicked
putting the controls in a textbox - they still get selected
Do you know a way of achieving my purpose?
The easiest way was to put a section marker after the buttons (that are configured as "in line") and protect first section from editing.
Click on Developer -> Restrict Editing -> Check Allow only this type of editing in the document and Select Filling in forms. Then, click on Select Sections and Select the first section.
Next, in the VBA code, to select all the text, I use this code:
Dim rngText As Range
Set rngText = ActiveDocument.Sections(2).Range
rngText.Select

Excel: Object Text Box can't do Carriage Returns in Protected vs. Unprotected Sheet states (w/ Text Unlocked)...why?

First and foremost, my due diligence rounded up a ton of answers regarding ActiveX Text Boxes, but nothing really about Object Text Boxes. For my project, I cannot use any ActiveX.
OK, so when a Sheet is Unprotected, an Object Text Box (from Insert > Shapes) works pretty much the way I want it to: the most important thing being that I can hit the Enter key and get a carriage return. Then, I go into the Shape Properties, and uncheck Lock Text, and protect the sheet.
Once the sheet is protected, though, the ability to do carriage returns (type Enter, and go down one line) goes away. Shift+Enter and Alt+Enter are no-goes as well.
Is it just not possible to have this functionality available? Are there any workarounds? Why does Excel hate me? Here are some of my ideas:
Unprotect Sheet when Text Box is clicked/activated, Protect when not
(couldn't figure out the syntax in VBA for this. "If Intersect..." is what I'm thinking)
Insert Word Doc Object (don't like this because one-click enters the
formula bar editing, and I can't get the font to stay)
Just use a merged cell and instruct users to double-click to enter
and use Alt+Enter for a new line.
The winning option for now is using a merged cell, but I may just have to see if ActiveX will work on our network. I really want to stick to the KISS principle here if at all possible for the end user...I don't mind coding in the backend to make it work, though.
Thank you for your thoughts!
EDIT: Here's some images to help...
Here's the functionality that I would like to have when my Sheet is protected:
Next, this is an ActiveX text box with it's properties window displayed (Developer > Design Mode > Properties). The properties that make it somewhat usable when the Sheet is protected are circled in red, the Multiline and Enter Key Behavior. But again, I'd prefer to not have to use ActiveX...plus, the user cannot change font color by line.
Finally, I found this interesting: There is another Text box under Form Control that is grayed out. From a search, it looks like this was taken away in favor of the drawing objects version of the text box...or maybe it's the same? The left is the drawing objects one, the middle is the grayed out Form Control, and the right is the ActiveX.
In sum, I would just like to see if there is a way to have the functionality of an unprotected Sheet's Shapes Text Box when the sheet is protected.
Assuming you are working with a TextBox shape, inserted from the ribbon, here:
Then you can use the optional parameter in the Protect method:
Sheet1.Protect DrawingObjects:=False
This will allow the user to edit text boxes on the worksheet, but the sheet itself will remain protected.
If you are using a Form Control (inserted from the Develper/Design ribbon) then you can set the .MultiLine property by accessing the shape's OLEFormat.Object:
Sub test()
Dim tb As Shape
Dim x As Object
'Get a handle on the SHAPE
Set tb = ActiveSheet.Shapes(2)
'You have to access its properties from the OLEFormat.Object:
tb.OLEFormat.Object.Object.MultiLine = True
End Sub
In my test, even on a Protected worksheet this allows the user to Shift + Enter to insert carriage returns:
Ctrl + Shift + Enter seems to work on a protected sheet.

Visual Basic 2010 using .left

i want to know if what is the thing that calculate when i call "object.LEFT" in visual basic express 2010, same thing as right bottom and .top..
thankz in advance! ^^
object.left is a property of a control that specifies its relative distance (in pixels) from the control's parent container.
For example: if you have object.left set to 50, then it will push the control in 50 pixels from the left side of the container (i.e. a Form in WinForms development or Page in ASP.NET development).
Yes, I could be more specific if you provided more specific detail about the specific object, and what your purpose was.
In VB there are .Left, .Top, .Width and .Height properties that are usually measured in screen pixels to define the position and size of a Control (ListBox, CheckBox, TextBox, etc) on a Form. Footnote: VBForms can be set to use twips, points, centimeters and inches as their basic measurement.
In Office (Word, PowerPoint, Excel) there are controls that are similar but NOT the same exactly as those in VB UI. They can be placed on a UserForm using these same properties. To place them on a Word document however, you need the .GetPoint method that allows you to specify a .Range object on your document and this function will fill-in the placement information
myWorkingDoc.Windows.Item(1).GetPoint ScPixLeft, ScPixTop, ScPixWidth, ScPixHeight, _
TblControl.Rows.Item(4).Cells.Item(1).Range.OMaths.Item(1).Range
The above line defines 4 Long integers: ScPixLeft, ScPixTop, ScPixWidth, ScPixHeight and a Range object in a word document, in the above case a Word Table named TblControl, the 4th row, 2nd (cell) column. WIthin a Word document window object the .GetPoint method gives one the relative placement, in pixels, within the document window. I use ScPixWidth and ScPixHeight to give me the size of the math equation (OMath object) so I can size an InlineShape to contain it.