MS VBA controlling Publisher - excel

This is my first post in this site. I've found suggestions in the past provided by this site, but I never had to ask something directly such as today.
I've been using Microsoft help files with the topic, but after given up and clicked on contacting Microsoft for help, it suggested to join this site.
I've been asked to create a macro to update various documents without Publisher. I never used Publisher and soon realized there's no macro record function.
The macro does functions that I need it to do with a few exceptions and 2 are listed below which i need help with.
FIND/REPLACE TEXT.
I'm able to use the above function, and I'm able to replace text however in one instance the document has 2 bullet's on an outline and i need to create a 3rd. I look for the last few words on bullet 2, but can't figure out how to do a carriage return or a simple 'ENTER' like if you were to do it manually in order to start a new bullet.
in Excel i use CHR(10) or CHR(13) but it doesn't seem to work here, even though i am coding in Excel. I found posts suggesting VbTab, VbCr, VbCtrl, but i never used those and can't seem to get them working.
FIND TEXT
Some documents are outdated and i don't want to create a new version (the code wouldn't make any changes, however it would still SAVE AS with a new document name. I need to verify if certain words exist and only then, proceed with the changes.
I found this code on Microsoft web site but... it only works the 1st time around.
.FoundTextRange - after the 2nd time around this object is always set to 'Nothing' even though i see the words i'm searching for.
Dim objFind as FindReplace
Dim fFound as Boolean
Set objFind = ActiveDocument.Pages(1) _
.Shapes(1).TextFrame.TextRange.Find
fFound = True
With objFind
.Clear
.FindText = "Urgent"
Do While fFound = True
fFound = .Execute
If Not .FoundTextRange Is Nothing Then
.FoundTextRange.Font.Bold = True
End If
Loop
End With
Any help would be appreciated.
Thanks,

I may have stumbled on an answer for the 2nd part. It seems the object for the publisher application is required in front of 'with Activedocument.find' = with AppPub.activedocument.find. On MS web site, it does not reference this.
The error then happens throughout the macro whenever 'Activedocument.find shows, it works once i apply the AppPub object reference.
If someone can suggest how to add new bullet points, that would be helpull.
I have other questions related to publisher...
How do you center a text box after it's been expanded? (i have to make it wide in order not to hide added text (wider and longer), but the wider change, only changes it to the right, not both ways.
how do you add a check box. The doc has existing checkboxes. When i copied the existing text box, that worked, but the box is very small. I tried Windings, but the box is different than the others.

Related

Programmatically list Excel VBA UserForm Event Procedures

First of all, I already found out how to list default event names of Excel UserForm Controls using Typelib Info referenced as TLBINF32.DLL.
I shared it here.
It is a part of my ongoing project to create codeflow diagrams and possibly VBA code obfuscator early alpha version available on GitHub.
The issue now, is, with trying to list Event Procedures of the UserForm itself:
Unlike listing UserForm Controls using TLI-ClassInfoFromObject(UserForm1.CommandButton1), I found out the hard way that I need to use TLI-TypeLibInfoFromFile("FM20.dll") because if I use ClassInfoFromObject(UserForm1), there is an error.
I also found out that I can use TLI-ClassInfoFromObject(ThisWorkbook.VBProject.VBComponents("UserForm1").Designer).
Using FM20.dll and .Designer methods both get 16 event procedure names.
I can manage/understand up to this far.
Then I manually counted the UserForm's event procedure dropdown list in Excel VBA Editor and found that there are 22 UserForm event procedures.
But after I ran the following code using TLI, the resulting list contains 16 event procedures only, as shown in the first photo.
I am using MSForms class/object from FM20.dll.
The code is as follows: (Needs Reference to TypeLib Information library at C:\Windows\SysWow64\TLBINF32.DLL)
Sub listUFEvents()
Dim t As TLI.TLIApplication
Set t = New TLI.TLIApplication
Dim ti As TLI.TypeLibInfo
Set ti = t.TypeLibInfoFromFile("C:\Windows\SysWOW64\FM20.dll")
Dim cci As TLI.CoClassInfo
Dim mi As TLI.MemberInfo
Dim i As Integer
For Each cci In ti.CoClasses
If cci.Name = "UserForm" Then
For Each mi In cci.DefaultEventInterface.Members
i = i + 1
Debug.Print CStr(i), mi.Name
Next mi
End If
Next cci
End Sub
6 events were not listed including UserForm.Activate and UserForm.QueryClose etc.
My question is, why those 6 event procedures were not listed?
If these event procedures were not picked up from the TypeLib in FM20.dll, where do they come from?
Object Browser also shows only 16 procedures.
Or did I do something wrong in using TLI library?
I admit that I am pretty far from becoming/being an expert.
I am still trying to understand how TypeLib Info works.
How do I get all 22 event procedure names?
I need the event procedure names to differentiate user-defined procedures from the event procedures in a UserForm CodeModule in my project which is about listing the procedure calls in a VBA project.
I can't find anybody asking the same question anywhere either.
Edit:08FEB2021
Added project userform image + zoomed one, to clearly show and better explain the question
In the following zoomed photo,
A->, UserForm controls' default event procedures' names
B->, UserForm default event procedure names
C->, User-defined Sub+Function residing inside UserForm CodeModule
Above image is zoomed for better clarity.
***********************************************************
I want to separate B from C like I did with A.
***********************************************************
So that we can know that default event procedures were NOT called directly.
The image below is presented to get a better idea of why I am needing to list the names of the UserForm event procedures.
Apology
I apologize for being a bit political (if you wanna call a function name politics!).
I truly am sorry to have to involve a bit of politics here.
I am not asking for anything except your awareness. Give me a negative vote if you want, for doing what a man needs to do when his country needs him most.
I just want to do something, however small it may be, as a citizen of Myanmar.
Normally, I am not interested in politics but the current situation calls for me to let the world know that Myanmar is currently under siege by a Military coup which forcibly removed democratically elected government and currently oppressing its citizens' rights.
Please bear with me and I hope you all can understand and empathize with me.
Thanks for your kind understanding.
The TLBINF32.DLL does what it is designed (coded) to do, so there is nothing you can do to make it recognize the five events related to MSForm's multiple "open/close" steps, or the MSForm's own window's Resize events. If you want to use them in your code you can, for example, create string constants for the event names you need, or keep them in a lookup table in a worksheet, or in a text file you will read, or whichever other way that suites your project.
As for listing Excel UserForm Controls, you do not need TLBINF32.DLL at all because it's already built (obviously, since TLBINF32.DLL just taps into this) into the MSForm class. To test this, please create a form, name it, say, "Form1", throw in a few controls and run the following simple subroutine from anywhere within the VBA project:
Sub ExamineControls()
Dim ctl As Control
For Each ctl In Form1.Controls
Debug.Print ctl.Name, ctl.Top, ctl.Visible ' anything else you need?
Next
End Sub
It does not matter whether the Form1 is opened or not.
I hope this is helpful.

Lotus notes - error accessing shared private on first use view from LotusScript

Good morning,
I have develop a note application which is used to make a booking. This application is used by multiple user at the same time.
I am quiet new to this development and now I would like to develop a functionality so that user can print a export data to excel.
I have created a view (Shared) where its Selection Formula is base on critical each user specify in a search form. I have problem when a user is being printing and yet finished, the other users is also clicking printing same time, the result of export data on the sides are the same to the one who created first.
I was thought may be using the kind of (Shared, Private on first Use View) but it generated an error [Notes error: Index is not to be generated on server ("view name") ] at the points where I called
view.Clear
view.SelectionFormula = formula
uiw.ViewRebuild
I have no idea how to solve this problem. Could you please advice how this problem could be solved?
Thanks your in advance for your great help.
Best regards,
Veasna
There are different ways to do this. One possibility is to use a "shared, private on first use" (spofu) view: then every user gets his own copy of the view, and they don't impact each other. But I think it is not a good idea to do it like that, as every user needs designer rights to change the selection formula of the view. This is something you do not want.
A better way would be to use a spofu folder for each user and put the documents in it like this:
Dim ses as New NotesSession
Dim db as NotesDatabase
Dim dc as NotesDocumentCollection
Dim folder As NotesView
Dim formula as String
Set db = ses.currentDatabase
Set folder = db.GetView("NameOfTheSpofuFolder" )
'Make it empty
Call folder.AllEntries.RemoveFromFolder("NameOfTheSpofuFolder")
'Search documents based on the formula
Formula = "Field1 = 2 & Field2 = 5"
Set dc = db.Search( formula, Nothing, 0)
Call dc.PutInFolder("NameOfTheSpofuFolder")
Spofu folders need a little "care" but usually they work quite nicely.
This code is not tested and just written down without syntax check etc. It might contain typos, but should give you an idea how to start.
You could create a Lotusscript agent to export the data the users specify.
Get the search criteria from the form, then use db.Search or (preferably) db.FTSearch to get the documents to export.
Now you can export the data of those documents to Excel, using one of the techniques described here:
http://blog.texasswede.com/export-from-notes-to-excel-3-different-ways/
If you want to export as CSV, you can use this code as a start: http://blog.texasswede.com/export-notes-view-to-excel-with-multi-value-fields/
According to this thread on the Notes 6/7 forum, there may be a workaround for this problem. You haven't shown enough code to know for sure. If you are using getView() to access the Shared - Private On First Use (SPOFU) view, that doesn't work. The workaround is to loop through the db.Views() array, checking both the Name and Readers properties in order to make sure that you get a handle on the private instance of the view instead of the shared instance.

Sharepoint 2007 Webpart variables problem on reload

I'm having trouble with the webparts variables... I came from standard ASP language, so, to me, store variables in session and other parts is the common way to do everything =)
Now i had to create a webpart, the wp has to write a graph from parameter and i cannot understand HOW variables works: i cannot understand WHEN saved and WHEN erased and other thing like this!
Let me explain: i have a web part with the configuration toolbar on the right in which i put the values.. Everytime a button is pressed or a value in the dropdown list changes, it raises an event which causes the "CreateChild" function..
Many times the data is "stored", other time they are not!
That's the way i used to store value (in the ApplyChanges override function):
WPChartGenerator wpParent = (WPChartGenerator)this.ParentToolPane.SelectedWebPart;
wpParent.WebUrl = txtWebUrl.Text.Trim();
And in the CreateChild event i get the value like:
WPChartGenerator wpParent = (WPChartGenerator)this.ParentToolPane.SelectedWebPart;
this.ddlWeb = new DropDownList();
this.ddlWeb.ID = "ddlweb" + wpParent.ID;
ddlWeb.SelectedValue = wpParent.WebService;
Now.. Sometimes this works, for example, when i push a button I invoke in the code of the button and then the code to store every value.. In some case (like buttons) this works, in other (like dropdown list index changed event) this fails and i found every object in the wpParent equal to it's initial value.
Another thing i noticed, is that in certain cases when an event is triggered, the first thing to be executed (even first than the event's associated code) il CreateChild (even first than OnLoad!!!)
Can anybody tell me what I'm doing in the wrong way? Do anybody has a good tutoria for this matter?
Thanks & sorry 4 my School level English =)
Forget to say that every variable has been implemented as a Property, like that:
[WebBrowsable(false)]
[Personalizable(PersonalizationScope.Shared)]
[WebPartStorage(Storage.Shared)]
public string WebUrl
{
get
{
return this.webUrl;
}
set
{
this.webUrl = value;
}
}
I can't see all the code there so I don't really know what you're doing wrong (i.e. do you actually have an ApplyChanges method) but from the way you've worded your question it sounds like you really need to start at the beginning, follow one of these walkthrough tutorials and make sure you understand the basics and then start adding in the code for your project.
MSDN - Creating Web Parts for SharePoint (VS2010)
MSDN - Walkthrough: Creating a Basic SharePoint Web Part (WSS 3.0)
Developing SharePoint 2007 Web Parts

Get Sharepoint store URL in Outlook?

I'm trying to write an Outlook 2007 VSTO add-in that lets you do some stuff with Sharepoint webservices. I'd really like to make it as simple as possible for the users; ideally, all that they would have to do is connect a Sharepoint list to Outlook. From there, my add-in would ideally grab the actual Sharepoint URL from the list and do its thing. Unfortunately, I can't seem to find where Outlook stores this information while running.
The best solution I've been able to find is to read in the files found in C:\Documents and Settings(username)\Local Settings\Application Data\Microsoft\Outlook*.sharing.xml.obi.
However, these files are only updated when you close Outlook. That means that the user would have to connect to the list, restart Outlook, and then things would work. I'd rather not have things get to that level.
It's almost like the information just magics its way into the sharing.xml.obi files. I've Googled, I've used OutlookSpy and in desperation I've used mfcmapi.exe, all to no avail. Where the heck does Outlook store this?
You can use the object model (or direct MAPI calls) to query this information from the outlook folder. First use the .isSharePointFolder property to locate your folder. The URL of the SharePoint List in outlook is then stored as the subject of a "hidden" message in the associated contents table.
Bonus tip: If you are not using it already, get yourself a copy of the excellent OutlookSpy. It makes figuring this kind of stuff out so much easier.
With Paul-Jan's pointer, I've figured this out. Since I hate it when I only find indirect hints while googling, here's exactly the code you need:
private string getSharepointURL(Microsoft.Office.Interop.Outlook.Folder SharepointFolder)
{
if (!SharepointFolder.IsSharePointFolder)
throw new Exception("Cannot get the SharePoint URL of " + SharepointFolder.FullFolderPath + ", because it is not a SharePoint folder.");
return (string)((object[])SharepointFolder.GetTable("", 1).FindRow("[From] = SharePoint").GetValues())[1];
}
That may be the ugliest return statement I've ever written. Here's what it does:
Calls Outlook.Folder.GetTable("",1). The first argument is a filter, which means "anything", and the second argument is equivalent to olHiddenItems. (I couldn't find the actual enumeration)
Gets the next row of that table whose sender (the [From] field) is "SharePoint". The information we want is always held in this hidden message.
Gets the values of that hidden message. This comes back as an object, but is secretly an object[].
Casts the values to an object[].
Gets the second item of the values, which is the url.
Casts the url to a string.
Fortunately, you can do all these steps yourself in OutlookSpy. That was a real help in figuring out how to get at this precious nugget of information.
Well, here is what I use... (C#3/VS2008, Outlook2007)
Outlook.Folder folder = GetSomeSpFolder(); // requirement :)
// Things to look for here, not in the columns by default
// the values can be found in OutlookSpy or perhaps MSDN (haha)
// this value refers to the SP site (not the full URL)
var SHARING_REMOTE_STORE_UID = "http://schemas.microsoft.com/mapi/id/{00062040-0000-0000-C000-000000000046}/8A48001E";
var table = folder.GetTable("[From] = SharePoint", Outlook.OlTableContents.olHiddenItems);
// setup columns to look through
table.Columns.RemoveAll();
table.Columns.Add(SHARING_REMOTE_STORE_UID);
if (!table.EndOfTable) {
var row = table.GetNextRow();
var siteURL = row[SHARING_REMOTE_STORE_UID];
Marshal.ReleaseComObject(row);
} else {
// No matching entry ...
}
Marshal.ReleaseComObject(table);
Also check out http://msdn.microsoft.com/en-us/library/bb176406.aspx
Happy coding!

Enable/disable editing of a form field from code

I'm not a Notes programmer, however, for my sins, have been working on some Notes features for an in-house project recently. I need to enable/disable editing of a field depending on circumstances. It seems to me to be a fairly standard feature, I need, but I can't find any information on how to do this anywhere.
In form setup (and other field's onchange) code, something like the following:
if some requirement = true then
textField.enable = true
else
textField.enable = false
end if
I've seen other places where there's a workaround of conditionally hiding paragraphs based on some code, having 2 paragraphs with opposite hiding conditions, one with an editable field, the other with a computed field. However, I don't know enough about Notes to see how this is implemented (I can see it done on other forms, but there seem to be some 'magic' steps within Notes which I either can't see or don't get).
[EDIT]
The reply from Kerr seems to be what I'm looking for, but I still can't find out where the InputEnabled property is located. Should have said in the initial question, I'm using Notes 7.0.3.
In fairness, it doesn't matter what the circumstances are for when to enable/disable the field, it's just some boolean condition that is set, in my case only on form loading so I don't even have to worry about this changing dynamically while the form is displayed.
I've got a few issues with Notes, my largest bugbear being that it's so tied so tightly to the Designer UI, which is utter shite. I can do this sort of thing programmatically in most GUI languages (C#, Java, Delphi, even VB), but I need to open property boxes in Notes and set them correctly.
This would be OK as an optional method, but forcing you to go this way means you can only work as well as the IDE lets you in this case, and the IDE here seems to actively work against you. You can't open multiple functions/scripts, you can't swap from one script to another without going back to the menus on the left, you can't easily search the codebase for occurrences of variables/fields (and believe me, this is a major failing for me because either Notes or the internal codebase in my case seems to make a lot of use of global variables!), you can only work with fields through the property boxes that get displayed, you can't edit code in Designer while debugging through the main Notes client.
While the Java side of the coding is better than LotusScript, it's still fairly crappy (why can't you debug INTO Java code?? Why do you need to re-import JAR files for each Java class, does each class have a different CLASSPATH???). Possibly this was improved in Notes 8, I hear it's based on Eclipse. Does anyone know whether this is true or not?
It would help to hear more specifics about the 'circumstances', but the most common way to handle this is to use a hide when formula on the field you want to enable/disable.
Technically you are not enabling or disabling the field, just hiding it, but usually that works just as well.
Since there are few events to work with in Notes, developers commonly use the document refresh as the 'event' to cause the field to hide or show.
Let's assume you have two fields called TriggerField and Subject. Say also you want to disable the Subject based on a value in the TriggerField. The easiest way to do so is to set the TriggerField as a Dialog List type and check the "Refresh fields on keyword change" option. This means when the value of the dialog list changes, the entire document will get refreshed.
Then in your hide when formula for the Subject field, you specify your criteria for when to show or hide that field. Anytime field values change, followed by a refresh of the document (i.e. form), that hide when formula will be re-evaluated.
There are other ways, depending on your circumstances, to solve this problem. If you want to let the user refresh the form themselves, put a button on the form that calls the #Command([ViewRefreshFields]) command. You can add any other formulas to that button before the refresh command if you want to make other changes to the form at the same time.
Another option is to make a certain field display-only. Then create a button that runs LotusScript to allow users to change that display-only field. In the script you can propmt the user for a value, set the display-only field, and then call for a document refresh.
In ND7 and up if you want to just disable the field for input, write an appropriate formula in the InputEnabled section of the field you want to disable.
So I have two fields one called Trigger, a checkbox with the value "On" and another Subject that is a text field. When Trigger is checked I want the value Subject to be enabled.
I simply put the following formula in the Input Enabled element of the field Subject:
Trigger = "On"
I also want this to be recalculated whenever the value of Trigger changes so I select the "Refresh fields on keyword change" option on the Trigger field.
If you're stuck in an older version you need to to hide paragraphs appropriately.

Resources