I'm trying to record a macro that will set the size of a pasted image to 6.5 x 4 cms and the image layout 'in front of text'. I usually set this by right clicking on the image and setting the picture properties but this isn't available when recording the macro. Using Shift-F10 does bring up the menu, but the option to set the image layout properties is greyed out.
Please help!
Thanks
Yes, that's interesting about the macro recorder...
If you need to do something like this in the future it will help you to know that an object with any kind of "text wrap" formatting (that "floats") is a Shape. An object that behaves like a character is an InlineShape. And you can convert between the two using ConvertToInlineShape / ConvertToShape. For future things of this nature that should give you a starting point :-)
The following code sample uses ConvertToShape so that text wrap formatting can be applied. (The conversion is an extra step involved that you don't have to do in the UI - Word does it for you.)
Before this happens the code changes the size, but it could also be the other way around, changing the size on the Shape object.
What else is happening in the code: When a picture is pasted inline it's not selected. So this code figures out how many pictures (InlineShapes) are already in the document up to the selection. After the paste the code then picks up the existing number of pictures up to that point, plus one, to get the picture that was just pasted.
The code uses CentimetersToPoints to convert the number of centimeters wanted to the Points measurement, since that's what Word uses to size graphical objects (and lots of other things).
How did I know to use wdWrapFront: When shp.WrapFormat.Type = is typed the VBA Editor will automatically show a list of valid entries for text wrap formatting. Similarly, when shp. is typed a list of valid properties for a Shape will appear, and so on. (This is called IntelliSense and is a wonderful help!)
Sub PasteAndSelectPicture()
Dim ils As Word.InlineShape
Dim shp As Word.Shape
Dim lNrIls As Long
Dim rngDoc As Word.Range
Dim rngSel As Word.Range
Set rngDoc = ActiveDocument.content
Set rngSel = Selection.Range
rngDoc.End = rngSel.End + 1
lNrIls = rngDoc.InlineShapes.Count
rngSel.Paste
' Debug.Print rngDoc.InlineShapes.Count, lNrIls
Set ils = rngDoc.InlineShapes(lNrIls + 1)
ils.width = CentimetersToPoints(6.5)
ils.height = CentimetersToPoints(4)
Set shp = ils.ConvertToShape
shp.WrapFormat.Type = wdWrapFront
End SUb
Related
I'm currently trying to program a CATIA macro to search through a specific text:"DD/MM/YYY" on a 2D CATIA drawing sheet and replace that same text with a user inputted text. (Basically to update the text box)
I'm currently new to VBA scripting language and have zero to no experience in doing this. I've researched extensively on this but found no codes close to achieving the problems that I am trying to solve.
Textbox contents to be replaced by user
what I wanted the CATIA macro to do
I'm quite sure that your date text string has a specific name in the title block, so search for that specific text string name and assign another value.
If you have a lot of drawings to do this task, you can do it in batch mode, open one by one drawings in a folder, replace the date, save drawing, close document...no input from designer, just assign the new date value inside your new macro.
This short snippet will search all Texts entities and try to replace with a fixed string:
Sub Catmain()
Dim oDoc As Document
Dim oView as DrawingView
Dim oText As DrawingTexts
Dim txt_to_src As String
Dim txt_to_place As String
Dim n As Integer
n = 0
Set oDoc = CATIA.ActiveDocument
Set oSheets = oDoc.Sheets
Set oViews = oSheets.ActiveSheet.Views
Set oView = oViews.ActiveView
Set oTexts = oView.Texts
txt_to_src = "STACK OVERFLOW."
txt_to_place = "REPLACED"
For Each srcText In oTexts
If srcText.Text = txt_to_src Then
srcText.Text = txt_to_place
n = n + 1
End If
Next
MsgBox n & " text frames have been replaced"
End Sub
This only searches all texts in the active view of the active sheet of the opened document.
Consider to use a more specific check criteria such Instr (check if a string is contained into another string), the equality used is just a representative check.
You'll probably need to cycle all views of a Sheet (i.e. all Items of oViews collection), and all Sheets of a document (i.e. all items of oSheets collection). Then extend to cycle all opened DrawingDocuments if you want.
Remember that an empty document with a title block already has 2 Views (background and Main) so if your drawing has, say, just 1 Front View, the script has to cycle through 3 views.
I have this code to put a border on all images in my Word document. Inline shapes as floating shapes. Works fine. All images have a border. But my images on the first page (like Logo) also have a border.
Can anyone help me out with code for deleting the borders around floating images on the front page? Or specific shapes?
Thank you.
Kem
The Selection.Information(wdActivePageEnd) command can give you the current page number and in your case all you need to do is set the current selection point or working range to the top of the document ... and now you know you are on page 1.
The second challenge is selecting or setting a working range to only the first page. I use the built-in Bookmark "\Page".
The third challenge is identifying the type of shape and for that you use the Shape.Type property. If you are going after images remember they could be embedded or linked so you have to use the two property types.
Finally, in your questions you are asking how to remove borders. Well IMO you don't have to remove them, you only hide them.
Here is example code that you can study and figure out how to integrate with your existing code.
Sub RemoveBorders()
Dim rng As Word.Range, shp As Word.Shape
Set rng = ActiveDocument.Content
rng.Collapse Word.WdCollapseDirection.wdCollapseStart
Set rng = ActiveDocument.Bookmarks("\Page").Range
For Each shp In rng.ShapeRange
If shp.Type = msoPicture Or shp.Type = msoLinkedPicture Then
shp.Line.Visible = False
End If
Next
End Sub
I have no idea how to set DataRange for DataLabels using VBA.
Powerpoint does not have recording capabilities as well.
Can anybody tell me to do this using VBA please?
The code to accomplish this is as follows:
Dim myChart As Chart
Dim mySerCol As SeriesCollection
Dim strRange As String
strRange = "=Sheet1!$F$2:$F$5" 'To hold the range for the new labels
Set myChart = ....[put in code to get the appropriate chart]
Set mySerCol = myChart.SeriesCollection(i)
mySerCol.ApplyDataLabels 'Turn on the datalabels for this series
'The next line sets the range to get the values from
mySerCol.Format.TextFrame2.TextRange.InsertChartField msoChartFieldRange _
, strRange, 0
mySerCol.ShowRange = True 'Show the values from the range
mySerCol.ShowValue = False 'Do not show the actual values of the points
Note that this will only do this for one of the series. To do the other ones, loop through i in the myChart.SeriesCollections(i) line.
****EDIT**** See other answer. I am leaving this here because it provides some information about several objects that could be used, but doesn't actually solve the problem.
This is not a complete answer to the issue, but this is too long for a comment.
I've searched through the documentation for the Datalabels and was unable to figure out how to do this (I assume that you want to be able to define the range that the labels come from using VBA). I was able to "check" the checkbox, but couldn't figure out where the range that is attached to it is. The appropriate code to check.
To check the checkbox, use this code:
myChart.SeriesCollection(i).ApplyDataLabels
where i is the series in question and myChart is a Chart object referencing your chart. There are a bunch of parameters to this method that will allow you to show different items (percentages, values, etc.), but none of the parameters is a range.
This defaults to the values of the series if you do not enter any of the optional parameters
It is then possible to turn this on and off using:
myChart.SeriesCollection(i).DataLabels.ShowRange = True/False
It is possible to change the caption of the Datalabels using:
myChart.SeriesCollection(i).DataLabels(j).Caption = "MY CAPTION"
This will change the caption one at a time, and it will replace the value that the "ApplyDataLabels" method puts in there. It would be possible to loop through the range to set the values, but this is likely not what you are looking for.
There's also this:
myChart.SeriesCollection(i).HasDataLabels = True
but this just seems to turn them on and off and resets the captions that you may have put in there.
MSDN link uses both the hasdatalabels property and the applydatalabels method, but it is not clear why they are using both: https://msdn.microsoft.com/EN-US/library/office/ff745965.aspx
Hopefully this can at least give you something to start with.
I'm relatively new to VBA and have only very limited programming experience in general, but would really appreciate some help!
The ultimate goal is to pass (formatted) text from a text box in PPT as a variable between presentations. I believe it is important that the (formatted) text be passed as a variable, because the variable will be used to generate the body of an email (that part of the code is done, but I'm trying to create the guts of that variable here). Unfortunately, I have no idea how to pass a variable in VBA. I think I've figured out how to grab the text, but the simple formatting (bold, text size differences, etc) is lost. Help please? :-)
Dim headlines
headlines = ActivePresentation.Slides(1).Shapes(1).TextFrame.TextRange.Text
You could set an object variable of type TextFrame and then set that to your shape's TextFrame in order to pass it between various apps.
e.g.
Dim myFormattedText as TextFrame ' or TextFrame2 to access all of the newer properties
Set myFormattedText = ActivePresentation.Slides(1).Shapes(1).TextFrame ' or TextFrame2
That way you have all of the text properties within that object.
This should help get you going. It copies a shape object, which contains all of the formatting properties you want, from one open presentation to a second open presentation. In reality, you would make the presentation, slide and shape references dynamic based on what you're trying to achieve but this is a working example to demonstrate the principle:
Option Explicit
' Macro to copy the first shape from the first slide of open presentation 1 to the first slide of open presentation 2
' Requires that 2 presetnations are open and that the first has a shape on slide 1
' Wriiten by Jamie Garroch of youpresent.co.uk
Sub PassTextBoxBetweenPresentations()
Dim oSrcShp As Shape ' Source Shape in Presentation 1
Dim oTgtShp As Shape ' Source Shape in Presentation 2
' Set a reference to a shape in the first presentation, in this case, the first shape on the first slide
Set oSrcShp = Presentations(1).Slides(1).Shapes(1)
' Copy the shape (with all of its properties) to the clipboard
oSrcShp.Copy
' Paste the shape from the first presentation to the second presentation
Presentations(2).Slides(1).Shapes.Paste
' Set a reference to the pasted shape
Set oTgtShp = Presentations(2).Slides(1).Shapes(Presentations(2).Slides(1).Shapes.Count)
' Do stuff with your pasted shape object
With oTgtShp
Dim headlines
If .HasTextFrame Then
If .TextFrame.HasText Then
headlines = .TextFrame.TextRange.Text
Debug.Print headlines
End If
End If
End With
' Clean up
Set oSrcShp = Nothing: Set oTgtShp = Nothing
End Sub
Does anyone know how when programmatically iterating through a word document, you can tell if a paragraph forms part of a table of contents (or indeed, anything else that forms part of a field).
My reason for asking is that I have a VB program that is supposed to extract the first couple of paragraphs of substantive text from a document - it's doing so by iterating through the Word.Paragraphs collection. I don't want the results to include tables of contents or other fields, I only want stuff that a human being would recognize as a header, title or a normal text paragraph. However it turns out that if there's a table of contents, then not only the table of contents itself but EVERY line in the table of contents appears as a separate item in Word.Paragraphs. I don't want these but haven't been able to find any property on the Paragraph object that would allow me to distinguish and so ignore them (I'm guessing I need the solution to apply to other field types too, like table of figures and table of authorities, which I haven't yet actually encountered but I guess potentially would cause the same problem)
Because of the limitations in the Word object model I think the best way to achieve this would be to temporarily remove the TOC field code, iterate through the Word document, and then re-insert the TOC. In VBA, it would look like this:
Dim doc As Document
Dim fld As Field
Dim rng As Range
Set doc = ActiveDocument
For Each fld In doc.Fields
If fld.Type = wdFieldTOC Then
fld.Select
Selection.Collapse
Set rng = Selection.Range 'capture place to re-insert TOC later
fld.Cut
End If
Next
Iterate through the code to extract paragraphs and then
Selection.Range = rng
Selection.Paste
If you are coding in .NET this should translate pretty closely. Also, this should work for Word 2003 and earlier as is, but for Word 2007/2010 the TOC, depending on how it is created, sometimes has a Content Control-like region surrounding it that may require you to write additional detect and remove code.
This is not guaranteed, but if the standard Word styles are being used for the TOC (highly likely), and if no one has added their own style prefixed with "TOC", then it is OK. This is a crude approach, but workable.
Dim parCurrentParagraph As Paragraph
If Left(parCurrentParagraph.Format.Style.NameLocal, 3) = "TOC" Then
' Do something
End If
What you could do is create a custom style for each section of your document.
Custom styles in Word 2003 (not sure which version of Word you're using)
Then, when iterating through your paragraph collection you can check the .Style property and safely ignore it if it equals your TOCStyle.
I believe the same technique would work fine for Tables as well.
The following Function will return a Range object that begins after any Table of Contents or Table of Figures. You can then use the Paragraphs property of the returned Range:
Private Function GetMainTextRange() As Range
Dim toc As TableOfContents
Dim tof As TableOfFigures
Dim mainTextStart As Long
mainTextStart = 1
For Each toc In ActiveDocument.TablesOfContents
If toc.Range.End > mainTextStart Then
mainTextStart = toc.Range.End + 1
End If
Next
For Each tof In ActiveDocument.TablesOfFigures
If tof.Range.End > mainTextStart Then
mainTextStart = tof.Range.End + 1
End If
Next
Set GetMainTextRange = ActiveDocument.Range(mainTextStart, ActiveDocument.Range.End)
End Function