Friends,
I'm using VBA to create Lotus emails populated from an Excel spreadsheet, and I'm stuck on a really silly point.
When I create a new section in the note, business rules require me to give it a border. They've been doing this manually for years and are used to doing this from the Notes UI. They create a new section, then go to its properties and then change it to have a border (please see the border and style part in the properties window in this screenshot).
I can't figure out how to add this border through VBA. Any ideas? I've tried changing the TitleStyle, but that only affects things like fonts and color. I have everything else done, just stuck on the border!
Thanks!
Mike
The NotesRichTextSection class doesn't give you any way to change the border, unfortunately. Rich text items in Lotus Notes aren't supported very well via the API, so often you'll find a mismatch between what you can do on the client vs. what you can do in code.
There might be a workaround if you're up for trying it. First you need to create a simple form in Notes that has a rich text field, let's call it Body, surrounded by a section. Setup the section to appear however you want, with the border set, etc. You'll also need another hidden text field, called Title, and you'll set the section's title to be computed based on that Title field.
Then in your VBA code you're going to create a new NotesDocument based on that form. You'll set the Title field, and you'll add content into the Body rich-text item. Then you'll need to call the ComputeWithForm method followed by the Save method. Finally, you can use the RenderToRTItem method on the document to put the entire document into your original note's rich text field. Make sense?
No guarantees that will work from VBA, but I've done similar things in the past using LotusScript and it did the trick.
You could just set the borders of the cells you are copying using the Borders() property.
Example:
Range("B2:C4").Borders.LineStyle = xlDash
Range("B2:C4").Borders(xlEdgeBottom) = RGB(255,0,0)
Related
I have an document in word, which has some fields to be filled, and an button to which I want to assign a macro. When that button is clicked, that same form with empty fields needs to be appended to the end of document, including the button (which can be clicked again and do the same thing).
Here is the document I have:
https://drive.google.com/file/d/0B_2kyqxMx5x4UkxfOHJhOGVPdnc/view?usp=sharing
The main problem with what you want to do is dynamically linking the button to the macro code to be executed. The most obvious type of button to use is the legacy ActiveX control in the Ribbon's Developer tab. But that requires its own procedure entry in the document's ThisDocument class module. While it's possible to add code to modules "on the fly" this involves disabling a security option.
A more straignt forward approach is to use the MacroButton field. This creates a clickable text within the document. It can display text or a graphic (so that it looks like a button) and is assigned the name of any public Sub that takes no parameters:
{ MACROBUTTON NameOfMacro Click here }
Ctrl+F9 to insert the field code brackets; Alt+F9 to toggle between field code and field result.
Graphics in Word 2010 and later:* The was a change to the graphics engine in Word 2010 which affects the behavior of graphics objects in the MacroButton field. Clicking the object triggers the Ribbon utility for working with graphics - the field code no longer "hides" the graphic. There are a number of ways you can work around this:
Use an IncludePicture field (which works with the old graphics format) to bring in an outside picture file. Once the linked picture is in the field it can be converted to a static picture by selecting the IncludePicture field and pressing Ctrl+Shift+F9. Word respects the old graphic format and the picture is click-able.
{ MacroButton NameOfMacro {IncludePicture "C:\\Path\\picture.jpg" } }
Use the old *.doc file format. Note that this will restrict some of the things that can be done with the document, but it will force use of the old graphics engine.
Instead of a MacroButton field, use the WindowBeforeDoubleClick event or WindowSelectionChange event to run the code.
*With the exception of unlinking the IncludePicture field (which I discovered myself), this information came from this discussion on the Microsoft Answers site
If you want to run the macro with a single rather than a double-click (the default) you need to run the following line of code. This applies to the entire Word application and needs to be run everytime Word restarts. You could put it in an AutoNew macro in the template / AutoOpen macro in the document:
Application.Options.ButtonFieldClicks = 1
The simplest way to store the entire content you want to insert repeatedly is as a Building Block (formerly known as AutoText).
BuildingBlocks are stored in templates. If your document is being created from a template, that would be the logical place. Another possibility would be a special template you use for this purpose. Normal.dotm can also be used but keep in mind this does sometimes get removed.
(Note: if you're using a template for the document that would also be the best place to store the macro attached to the macro button.)
Once this is set up, all your code needs to do is insert the BuidlingBlock at the end of the document.
To avoid an XY problem, here's what I'm trying to accomplish: when a shape is selected, I want detail text about that shape to appear on the screen.
I first tried using Shape Data, but it supports only single-line name=value pairs. My detail information is an arbitrary, multiline text blob.
My next thought was to used the shape's ScreenTip (aka tooltip) to hold the text data, then write some VBA code to handle the _SelectionChanged event. When a shape is selected I want to copy it's ScreenTip text into the text of another object (my details panel).
I got the _SelectionChange event-handling working, but poking around the Selection object in the debugger I can't find any property of the selected object that exposes the ScreenTip information.
Is Visio's programming API too anemic to support his kind of thing? Is there another way I might be able to do this? Is there another tool that might be better for this (preferably free)?
Visio's API is capable of doing this, handily.
It seems you're not aware of Visio's shapesheet, which is where the screen tip text is stored, along with pretty much anything you'd want to know about a shape.
To access the screen tip text you simply read the Comment cell from the selected shape's shapesheet:
Application.Selection(1).CellsU("Comment").ResultStr(visNone)
This code will return the comment text.
You're on the right track using the SelectionChange event, though of course you're checking that the selection count = 1, or at least >0.
I'm working on a VBA macro to automatically add hyperlinks within a drawing file, so that when a certain word is mentioned in the text, I can link to another page in the drawing.
According to MSDN and Visio's help, a Hyperlink object can be associated with a cell, characters, row, or section object. However, I can't find any way to actually associate a hyperlink with anything but a shape.
So the question is, how can I hyperlink a single word within a paragraph of text in a single shape in Visio?
I'm only familiar with two ways to trigger a hyperlink navigation within Visio:
Add a Hyperlink to a shape and click on the shape (or select the hyperlink from the shape's context menu).
Add a call to the Hyperlink shapesheet function in a cell formula. Making a change that triggers that cell's recalc would then follow the hyperlink.
The best idea I can think of, and it isn't very good, is:
Make sure your shape is a group - if it isn't, convert it to group.
Change the group's properties to SelectMode=visGrpSelModeMembers1st and DisplayMode=visGrpDisModeBack.
Drop a new shape, sized and centered over the word in question. Make the new shape transparent (partial transparency here could be used for highlighting).
Change the DblClick event's formula to "Hyperlink("yourURLhere")".
Add that shape to the group.
Now, double-clicking on the word should actually involve double-clicking on the new subshape, which will trigger the hyperlink. This is really only viable if your shape is designed to work with this idea - many out-of-the-box shapes will not work well here, as steps 1 and 2 can have ugly side-effects.
I hope someone else knows a more elegant way around this problem.
I'm trying to create a simple text field for WYSIWYG editing. However, I only want to allow certain types of formatting (e.g. Bold, Italic, Underline and a single heading type but no colors or different fonts.)
The issue is if I use an editor that can accept formatting, someone can create or copy formatted text in another program, then simply paste it into the text field and all that formatting goes with it, allowing things I'm not interested in, such as different fonts, colors, etc. I don't want to allow that.
At best, I want to automatically strip out any formatting that I don't support. At worst, I want to simply paste whatever as plain text making them have to reformat it. But in no case do I want to just dump the clipboard to the text area.
Any thoughts on how to do this?
I would recommend creating a new text field/text area class and creating an EditPaste menu handler that (a) does what you're looking for in terms of handling the clipboard's text and (b) returns true to prevent the default pasting from happening. This is safer than using the Key down events because the user might manually select paste from the edit menu.
You can access the text on the clipboard by creating a Clipboard object.
To subclass the textfield and intercept the paste menu command:
With your Project open, go to Project Menu > Add > Class
Select the new class in the project's tab and in the properties panel set the super to TextField
Double-click on the class to edit it
Click the "Add Menu Handler" mid-toolbar button in your class
Change the menu item name to "EditPaste". Put your code in before the "return true" and be sure to leave the return true in there.
Your code can then format and paste the text manually and override the default paste function.
Any command-V or control-V in that text field will cause that menu handler to fire. Any contextual menus would be added by you anyway since real basic does not create the default contextual menus, so you'd have control over that as well.
To add the text field to a window, just change the filter above the objects list to Project controls, and drag the class in from there.
You could intercept the paste yourself by intercepting it in the KeyDown events. Then, you could look to parse it yourself. That could be kind of tricky but I think that's about the only way you could do it.
It might just be easier to parse the resulting StyleRun after the paste and strip out formatting you don't want.
Alternately, you could look at the Formatted Text Control from True North Software and override the paste methods of the control (you get all the source) and just handle it yourself.
Either way, I think it will be a fair amount of work.
For example, I want the Title fields in the body and the page headers of the document to be updated automatically whenever the Title field in the document properties panel is changed. I know how to update the fields, but I want to know the name of the event that will tell me when the document properties have changed.
Your help will be appreciated. Thanks.
I also asked it on the MSDN Forums.
You can certainly check for these kinds of things in some of the events, such as DocumentBeforeClose or WindowSelectionChange, but this may be overkill. Instead, you could just use fields - they will update automatically. For example, go to Insert and then click on Quick Parts and then Field... Go to the Document Information section in the dropdown on the left and choose Title. Then, insert that and go back to the Home tab on the Ribbon and set its style to Title.
You also mention you also want page headers - are those properties you're setting in the Document Panel?
Word doesn't have any events like that. The best you might be able to do is use the selection change event, which will happen fairly often, but then you have to check all the propertiers of all the documents.
I think you're trying to do something that Word doesn't normally do. There are certain times when fields are updated and that's it. Teach you users how it works.