VBA in Word: CopyAsPicture method ignores text size as well as some font faces - vba

The CopyAsPicture method in VBA in Word (I am using Word 2010 and 2016) is to transform a given piece of text (some string selected in the document) into a picture.
Microsoft provides this sample script in its tutorials:
Sub CopyPasteAsPicture()
'Origin: https://learn.microsoft.com/en-us/office/vba/api/word.selection.copyaspicture
ActiveDocument.Content.Select
With Selection
.CopyAsPicture
.Collapse Direction:=wdCollapseEnd
.PasteSpecial DataType:=wdPasteMetafilePicture
End With
End Sub
For testing the CopyAsPicture method I used however the following script which I found in a related question in this forum:
Sub CopySelPasteAsPicture()
' Take a picture of a selection and paste it at the document end
' Source: https://stackoverflow.com/questions/8888145/convert-text-to-image-in-microsoft-word
With Selection
.CopyAsPicture
End With
ActiveDocument.Content.Select
With Selection
.Collapse Direction:=wdCollapseEnd
.TypeParagraph
.TypeParagraph
.PasteSpecial DataType:=wdPasteMetafilePicture
End With
End Sub
I tested this but I find two problems with it:
1) Text size is ignored. Text sized, say, 28 pt will be rendered in the resulting picture as 12 pt or something like that
2) Not all font faces get recognized. I have some special fonts (both in otf and ttf) that I want to picturize that way. These fonts are ignored, and instead I get a picture of a standard font (Times New Roman or whatever).
I do not find help for these issues in Microsoft's VBA documentation.
Additional information:
1) Why do I want to do this? I use some rare fonts that people do not have usually, and including them into the .docx also does not work reliably. I have to share these documents with colleagues, and they should be able to see also the characters from the special fonts.
2) Picture generation works with cyrillic characters in standard fonts. That's good so far.
3) Picture generation also works with fonts that have cliparts instead of pictures (such special fonts are used e.g. for childrens books or textbooks for people to train reading and writing)
4) The font that in my case does not get picturized (but replaced by pictures of some standard system font) is a font I got as .otf, but I transformed it to .ttf (because I thought I could then include into the documents, but this did not work either). - I did so far not test if it would work with the original otf, but I doubt it because there was so far no problem with ttf versus otf fonts.
Question:
I would like to understand why font size and some font faces are ignored.
Of course, ideas how to solve this are also welcome.

.PasteSpecial DataType:=wdPasteMetafilePicture
A metafile picture is meant to retain font data. So when the document is opened on a device that doesn't have that font Word will follow its font substitution rules. I also vaguely recall that there is a font related bug in the metafile format.
I suggest that you play with the other paste data types and see what works best for you.

Related

Autocorrect Word 2010 (VBA)

For my problem I tried different things and none worked: I am flexible about the way to actually solve it, so I think it's best to begin with the purpose.
I get long word files and I need to do some quality checks and proofreading. There are a lot of words in the file that are not capitalized correctly. I want to get this in automatic (no a normal grammar software/add-on won't do)
I have all the entries in my auto correct file, in word files (quite huge better not use them) and in an excel spreadsheet (wrong entry - correct entry).
Refreshing the document doesn't do the trick. If I pick a word from the list and select it and press the space-bar then it gets changed so I "wrote" a Macro for that
Sub Try()
For Each sentence In ActiveDocument.StoryRanges
For Each w In sentence.Words
Selection.MoveRight Unit:=wdWord, Count:=1
Selection.TypeText Text:=" "
Selection.TypeBackspace
Next
Next
End Sub
The thing "worked" i.e. it runs and you can see the cursor speeding through the screen but no words get changed. So I am thinking that Autocorrect get's somehow disabled while Macros are running.. Anyone has a hint? ideally knows a way around it?
Worst case I thought of putting the text in an excel file and writing a macro that for each line of text checks each word against my original list and "if match then substitute" but it doesn't seem too easy (at least for me)
Cheers
I hope that I could explain myself
This Pseudo Code / Outline should get you started:
In Word you can create an instance of Excel and open your spreadsheet:
https://stackoverflow.com/a/24196120/3451115
You can then Loop through your list of WrongWords:
https://stackoverflow.com/a/1463308/3451115
For each WrongWord do a Find and Replace:
VBA to find and replace a text in MS WORD 2010

Set PPT Font to 'Body' Type

I am not able to paste the entirety of my code, but the crux is that I have a textbox in PPT 2013, myTb, that I have (programmatically) pasted some text into. I now want to perform the following two actions:
See if the original text was the PPT 'body default' font (e.g. 'Calibri (body)' vs. 'Calibri' in the MS Ribbon)
If it was the body default, set the new text to also be the body default.
I can't seem to figure either part out, even though I have experimented with reading/writing from/to most of the Shape.TextFrame[n].TextRange.Font.Name... fields. I also had two confounding points to ask about, regarding the Shape.TextFrame.TextRange.Font.NameComplexScript field:
This field does not seem to be a 'complete' indicator of body-default vs non-body-default font. The reason is that if this textbox is originally the body-default ('Calibri (body)'), it will read '+mn-cs', but then I can change the font to the non-default variant ('Calibri'), and it still reads '+mn-cs'.
I then proceed to change the textbox to an entirely different font, which changes this field to the font's name as expected. However, if I then change back to the body-default font (or any other font, for that matter), this field remains on the previous font's name.
To set the font to the body or heading font, you need to use a weird bit of syntax:
{object}.Font.Name = "+" + FontType + "-" + FontLang
Where:
FontType is "mj" or "mn" for Major (headings) or Minor (body) respectively.
FontLang is "lt", "cs" or "ea" for Latin, Complex Scripts or East Asian
For example to set the font to the theme's body text font for Latin text:
ActivePresentation.Slides(1).Shapes(1).TextFrame.TextRange.Font.Name = "+mn-lt"
A bit late to the party, but I found this in case anyone needs it.
Edit: This is C# code, using the Interop PowerPoint namespace.
string headingsThemeFont = Globals.ThisAddIn.Application.ActivePresentation.SlideMaster.Theme.ThemeFontScheme.MajorFont.Item(MsoFontLanguageIndex.msoThemeLatin).Name;
string bodyThemeFont = Globals.ThisAddIn.Application.ActivePresentation.SlideMaster.Theme.ThemeFontScheme.MinorFont.Item(MsoFontLanguageIndex.msoThemeLatin).Name;

Different PPT templates reacting different on the same macros

I'm new here, so I might have not seen a possibility to upload my problem files, which would make it easier to describe the problem.
Edit: The files a here: https://drive.google.com/file/d/0B--IbmtX58h8TnVrdlRyUXZ5a2dEOVJBQkplVjFuVEVMVXhJ/view?usp=docslist_api
and: https://drive.google.com/file/d/0B--IbmtX58h8TFR6d3FkWlZpSGFVUGF5bHVhRTR5ZTlnbXAw/view?usp=docslist_api
(Thank you for the idea, Steve)
What it is about:
I have two documents with different master templates reacting completely different on the same set of macros and I have no idea how and why this can happen and how to repair or avoid it.
Two of the macros just create objects - one is a single textbox, the other one a group of a rectangle and a textbox . The first mentioned appears on the position defined in the code in one of the templates, but a bit below it in the other one. Even more strange is the behavior of the group. The rectangle appears on the correct position in both of the templates, the textbox only in one of it.
Next is a macro for increasing the paragraphing between text lines by 3 pt. It works fine in one template, but in the other template it increases the spacing by 43.2 pt!
Macro number four is made to set back the paragraphing space after back to 0. This one works fine in both templates.
Funny enough, the mistakes appear in opposite to each other. The single textbox and the group produce their error in the template, where the spacing tool works fine, and the spacing tool does strange things in the template where the single textbox and the group work well.
Any idea will be appreciated!
Thanks,
RG
I work with PowerPoint 2010.
Your footnote is getting misplaced because the default text settings in one presentation are different from those in the other; in this case the auto fit setting.
' in this section of your FOOTNOTE routine:
With .TextFrame
' Add this next line and it will work as expected
.AutoSize = ppAutoSizeNone
.TextRange.Text = "Note: " & vbCrLf & "Source: "
.VerticalAnchor = msoAnchorBottom
Likewise, in your SectionMarker subroutine:
With .TextFrame
' add this
.AutoSize = ppAutoSizeNone
' then the rest of your code
Then it all works as you'd expect. Or at least, it works the same with both templates.

VBA Word Selection.TypeText changing font?

I have a font which has lots of special unicode characters in, I would like to type them into a word document using a macro.
A very simplified version looks like this:
Sub Macro2()
Selection.TypeText (ChrW(58081))
End Sub
I can see using BabelMap (a font viewer), that the character at decimal 58081 is the one I want to enter.
The Issue
When I run this macro, the font changes from the font with the special characters to "Calibri" which is the default. This causes the character to show up as a square box similar to 
If I then manually highlight the square box and change it to my desired font, it corrects itself and shows up.
What I have tried
I have tried setting the font again before typing the text, it doesn't make a difference:
With Selection
.font.Name = "MyFont"
End With
Selection.TypeText (ChrW(58081))
I have also tried adding to the macro to go back and change the font after inserting it. This doesn't make a difference either, the code I use is this:
With Selection
.font.Name = "MyFont"
End With
Selection.TypeText (ChrW(58081))
Selection.MoveLeft Unit:=wdCharacter, Count:=1, Extend:=wdExtend
Selection.font.Name = "MyFont"
Selection.MoveRight Unit:=wdCharacter, Count:=1
A useful observation
When I enter a character within a normal set, e.g:
Selection.TypeText (ChrW(97))
This works without changing the font as I expect - why does the font change when I enter 58081?
This is only an idea: there is a difference between a paragraph having a font and a [sequence of] letter[s] having a font. If the paragraph has your myFont font, then the inserted text should be your font; otherwise it may revert to the paragraph's font (default for all text of the paragraph unless set to a different font).
If the selection is empty, i.e. you are refering to the insertion point, and you set the font, then the font for the next character is set. However, the TypeText method inserts it before the insertion point, so your set font has no effect.
As for your last attempt, to select the inserted character and set its font, I have no idea why that shouldn't work. Try following setting the font to print the size and font name of the selection (the selection should now be 1 characters in size).
You might also try using the InsertAfter or InsertBefore methods of the Selection object.
If you want to use Selection, this here worked just fine for me:
With Selection
.Font.Name = "Arial Unicode MS"
.Text = "Umlaut test ä ö ü ß"
End With
Many thanks for these ideas, they gave me another thing to look at. In the end, I found even if I copy/pasted a character from another location into the document that it was changing to font to Calibri. When creating a brand new document with nothing else into it and running the macro in my question, I had the same issue. However, I have an old document that was created around 2003 and I found when running even on the same version of office (2013 I am on), the macro works. I think something is going on when creating word documents, perhaps some default setting or perhaps some internal format differences, as my above macros work fine on the old document but not on any new documents I create.
My final solution is to use the old document, copy all my macros into it, and it works fine, even saved as a dotm file and when saved using my 2013 version of office. I am still totally at a loss as to why this is. I can still create new documents on which my macro does not work. Both files are .dotm, the only difference is the machine they were originally created on the version of office.
I hope this helps anyone else with the same problem, it's cost me about a day of pulling my hair out.

Convert text to image in Microsoft Word

I have a large book written in Microsoft Word and want to create a macro that will find all text using a predefined style and convert that text to an inline image. This text will be in Arabic and generally no longer than 4-5 lines. Is this possible?
UPDATE: Here's an example to show what I'm referring to:
I want to replace that entire line in Arabic with an image (as if I cropped this attached image to only include the Arabic and then replaced the line in Arabic with the image).
The reason I want a macro or script to do this is because there are hundreds of such lines and updating them one by one is cumbersome plus that will make modifications difficult later on.
UPDATE2: I found an interesting option here: http://windowssecrets.com/forums/showthread.php/31344-Convert-Text-to-an-Image-of-Text-in-VBA-(Office-2000-Sr1a)
It looks like you can cut a piece of text and then "Paste Special" as an image. So if there's a way to automate that that might work.
This is not an answer although I hope it will grow into a community answer. At the moment it is an exploration of what is required to solve the problem.
I know from the discussion when this question was posted on Super User that Abdullah wishes to publish his book on Kindle. So the question is really about how to get a document in English and Arabic ready for publication as an e-Book.
The Kindle does not support Arabic. The number of languages it does support is slowly increasing but there is no evidence I can find that Amazon has plans to add Arabic in the foreseeable future.
The format behind an Amazon e-Book is a cut down version of HTML. If a Word document containing Arabic letters is exported to HTML, the Arabic letters are included as character entities; for example: “ﭐ &#amp;64337; ﭒ ﭓ”. Importing the original Word or the HTML version to Kindle, results in the leading bits being discarded so these characters are displayed as P, Q, R and S instead of “ﭐ ﭑ ﭒ ﭓ (Alef Wasla isolated form, Alef Wasla final form, Beeh Wasla isolated form and Beeh Wasla final form).
I have tried Abdullah’s idea of saving some Arabic letters in a PNG file and creating an HTML file containing <p> … </p> <img src= “Arabic.png” > <p> … </p>. The appearance of this file on my Kindle 2 is perfectly acceptable so this has the potential to be a solution. The question is: how can the necessary conversions be performed?
We need to extract each Arabic string from either the Word document or its HTML equivalent and import it into a program that can convert them to PNG files.
The only way that I know of automating this would be to copy each string to a slide within PowerPoint. With PowerPoint’s SaveAs option it is possible to save each slide as a separate PNG file. The slides are named: SLIDE1.PNG, SLIDE2.PNG, SLIDE3.PNG and so on in sequence which would allow a macro to relate the results to the original strings. It would then be possible to replace the Arabic strings in the HTML file with the image elements. None of this would be too difficult to automate but there is a problem with the slides all being the size of the PowerPoint page. The page could be made smallish but what we need is for each slide to be cropped to just bigger than that slide’s text. I cannot think of any way of automating this cropping.
Does anyone have a better approach than converting each Arabic phrase to a PNG file?
I have been looking for PNG editors with some sort of command line interface but can find nothing that would be easier than using PowerPoint. Does anyone know of an alternative to PowerPoint?
Does anyone have any suggestions for automating the cropping of each image? When a string is placed in a PowerPoint slide it is possible to set its width to, say, 6.5cm (which looks good on my Kindle) and get the height determined by PowerPoint. This could be saved for later use if anyone knows how to use it.
Implementing solution
Pending any suggestions for improving the approach described above, the following outlines how I would implement it.
I would not attempt to process the Word document. I would save it as a Web Page, Filtered HTML file, which is a required step on the way to creating a Kindle eBook, and process that.
Within the HTML file created from my test document, the Arabic phrase comes out as:
<p class="MsoNormal"></p>
<p class="MsoNormal" align="center" style="text-align:center"><span dir="RTL"
style="font-size:24.0pt;font-family:Arial">
&#64336;&#64337;&#64338;&#64339;&#64340;&#64341;
&#64342;&#64343;&#65153;&#65154;&#65276;&#65275;
&#65274;&#65273;&#65246;&#65226;&#65227;&#65228;
</span><span style="font-size:24.0pt"></span></p>
<p class="MsoNormal"></p>
<p class="MsoNormal"></p>
I assume Abdullah's document will result in something similar. Note 1: the above is a random collection of Arabic letters. Note 2: they are held left-to-right in reading sequence even though, when displayed or printed, they are read right-to-left.
The whole of this block will have to be replaced with something like:
<br><imc src="xxxx.png"><br>
where the file xxxx.png holds an image of the Arabic text.
The file names, such as xxxx.png, could be systematic (A001.png, A002.png, ...) but I would have thought that transliterating the first ten or twenty characters of the phrase from the Arabic to English alphabets and using the result, with a numeric suffix, as the file name would be more convenient.
I would hold the records necessary to manage the process in an Excel worksheet. I would place the VBA code in the same workbook.
The steps in the conversion process that I envisage are:
VBA macro to extract Arabic strings from latest HTML file and add new strings to the Excel worksheet. (More about the Excel worksheet later.)
VBA macro to create PowerPoint file, with one slide per new string, and use SaveAs in PNG format to create one PNG file per slide before discarding the PowerPoint file.
Human to crop each PNG file. (There appears to be no way of automating the cropping so this task will be minimised by use of data in the Excel worksheet.)
VBA macro to rename each slide from SLIDEnnn.PNG to its permanent name and to record the permanent name in the Excel worksheet.
VBA macro to update the latest HTML file by replacing the block containing the Arabic phrase with the appropriate HTML IMG element.
The Excel worksheet needs two columns: Arabic phrase and PNG file name. If there is any risk of the worksheet being sorted between steps 2 and 4, we may need a sequence number as well.
Macro 1 will extract an Arabic phrase from the HTML file, look down the list in the worksheet for this phrase and add the phrase at the bottom if it is not already present.
Macro 2 will look for phrases in the worksheet that do not have a PNG file name. These new phrases are the ones to be written to the PowerPoint presentation. That is, a phrase only goes into this process once.
Task 3, cropping each PNG file, will be a pain. All I can say is that it will only be once per phrase.
Macro 4 will assume that the SLIDE001.PNG, SLIDE002.PNG, … are in the sequence of phrases without PNG files in the worksheet. If this might not be true (because the worksheet has been sorted) we will either need a sequence number or to retain the PowerPoint file. The macro will assign a unique name to each new phrase, record this name in the worksheet and rename the PNG file.
Macro 5 creates a new copy of the latest HTML file using the contents of the worksheet to determine which phrase to replace with which PNG file.
This process is not ideal but it will achieve the desired result and has no obvious complications. Any suggestions for improving it?
Before you begin these instructions, press record in the Microsoft Word macro editor, so you can see what the VBA code is.
I'm wondering if this will be easier if you convert the docx file to .rtf (rich text format) and replace that line with an image? Go to File > Save As.. > name it "old.rtf", then replace the line with an image and Save As.. again and name it "new.rtf" and then download Beyond Compare or your favorite diff program to see what happened. It should be easy to do this pro-grammatically if you choose to. I think working in text would be easier than Microsoft's binary format unless you can find a good library to modify their doc or docx formats.
Sub CopySelPasteAsPicture()
' Take a picture of a selection and paste it at the
' document end
With Selection
.CopyAsPicture
End With
ActiveDocument.Content.Select
With Selection
.Collapse Direction:=wdCollapseEnd
.TypeParagraph
.TypeParagraph
.PasteSpecial DataType:=wdPasteMetafilePicture
End With
End Sub