Ms Project VBA Macro Organiser to subproject copy issue - vba

I have a simple line of code that attempts to copy text field via project organiser from a Master project/Global.mpt to subproject within the master project (active project). I have tried multiple ways but i'm failing either with
'Run-time error 1101, the file Schedule 1" was not found Or, "This value is not valid in this situation, check the field to see if it requires a text, date or a number, and that you typed the information correctly".
Appreciate your help. Thanks
'OrganizerMoveItem Type:=pjFields, FileName:="MASTER SCHEDULE.mpp", ToFileName:=" Schedule1.mpp",
Name:="Text27"
'OrganizerMoveItem Type:=pjFields, FileName:="C:\xx\MASTER SCHEDULE.mpp", _
'ToFileName:=ActiveProject, Name:="T27(Text27)"
OrganizerMoveItem Type:=9, FileName:="GLOBAL.MPT", _
ToFileName:=ActiveProject.Subprojects("Schedule1.mpp"), Name:="T27"

The issue is that the subproject file needs to be open in order to use the Organizer to move customizations into it. Viewing the subproject's tasks in the master schedule is not the same as the subproject file being open.
This code will loop through the subprojects and copy the customized Text27 field to each one by opening it, using the Organizer, then closing and saving it.
Sub CopyCustomFieldToSubprojects()
Dim master As Project
Set master = ActiveProject
Dim prj As Subproject
For Each prj In master.Subprojects
FileOpenEx prj.Path
Projects(prj.SourceProject.Name).Activate
Application.Alerts False
OrganizerMoveItem Type:=pjFields, FileName:=master.Name _
, ToFileName:=ActiveProject.Name, Name:="T27 (Text27)"
Application.Alerts False
FileCloseEx pjSave
Next prj
End Sub
Note that the OrganizerMoveItem method expects a file name (string) for the FileName and ToFileName parameters rather than a Project object (e.g. Filename:=master.Name).

Related

Microsoft Project pool resources - count problem

code from learn.microsoft:
Dim R As Long, Names As String
For R = 1 To ActiveProject.Resources.Count
Names = ActiveProject.Resources(R).Name & ", " & Names
Next R
MsgBox Names
Works great when resources are defined in project file.
But when you use resources only in subprojects Resources collection is empty.
Adding new resource manually does not any changes - still count 0.
Using ribbon and Add Resources - counts this resource but other not.
How can I count resources from subprojects in main project?
When I terminate link to subprojects Resources collection count correctly.
Any ideas?
Sebastian, There is no error. I assume the "main project" you reference is a dynamic master. In a master project, subprojects are not part of the master, rather, the master contains pointers to each subproject. So when you run code in a master that loops through the Active.Project, the loop is looking for objects in the master and the master has no resource objects. Here is a modified version of your macro that will show the names of all resources in the resource pool, assuming all subprojects are using the pool. If there is a mixture of subprojects sharing and/or using their own resources the code will need to be modified.
Names As String
Dim Res As Resource
For Each Res In ActiveProject.Subprojects(1).SourceProject.Resources
Names = Res.Name & ", " & Names
Next Res
MsgBox Names
End Sub
The solution given by john-project solves the problem.
Browsing a resource collection with Resources collection remains problematic in one more situation: the project file contains its own resources separated by a blank line inserted with the insert key.
Such a line has an identifier but all fields are empty. Browsing resources using a collection generates an error (e.g. when reading the resource name).

Setting Directories and the If Len(Dir(... statement in VBA

I have a file exists under this path:
//path/folder1/folder2/datafile.gdp
It is an input to an external program being called from vba in this manner:
Sub RunProgram()
Dim wsh As Object
SetCurrentDirectory "\\path\"
ChDir "\\path\folder1\folder2\" 'Set Directory
Set wsh = VBA.CreateObject("WScript.Shell")
check = CurDir
Statusnum = wsh.Run(Command:="program.exe ""\\path\folder1\folder2\datafile.gdp""", WindowStyle:=1, waitonreturn:=True)
But on the final line, including \path\folder1\folder2\ before the input file name appears to cause the external program to want to write some files into a duplicated directory that doesn't exist, causing an error. It used to work in this format before the .exe was updated by an external company. It now wants to write some files here, all prefixed with the name of my input file:
\\path\folder1\folder2\PATH\FOLDER1\FOLDER2\
Hoping to fix this, I changed the final line of the code to this, following some comments on a previous post here on SO:
Statusnum = wsh.Run(Command:="program.exe ""datafile.gdp""", WindowStyle:=1, waitonreturn:=True)
Since the directory is set correctly prior to calling the .exe, I thought removing the path for the input file would solve the issue.
The program now launches, but doesn't appear to load the input file with it and no longer runs calculations automatically in the background as it should. Instead, it launches and the main .exe window pops up to the user as if it had just been launched for setting up a new project, calculations don't occur automatically.
To check which directory the VBA code was try to pull my datafile.gdp from, I created these loops directly before calling the .exe:
If Len(Dir("\\path\folder1\folder2\datafile.gdp")) = 0 Then
FileIsMissing1 = True 'I use Excel-VBA watches to break if true
End If
If Len(Dir("datafile.gdp")) = 0 Then
FileIsMissing2 = True
End If
Bizarrely, neither of these loops causes a break. The file only exists in
\\path\folder1\folder2\datafile.gdp
Not in the duplicated directory... so why are both of these statements satisfied? Does entering the directory make no difference even when the current directory has been set? The current directory seems to be impacting the line:
Statusnum = wsh.Run(Command:="program.exe ""\\path\folder1\folder2\datafile.gdp""", WindowStyle:=1, waitonreturn:=True)
But not these if loops, and I'm not sure why.

Update VBA code module in distributed MS Project global.mpt files

I am responsible to modify the Global file of MS Project. It contains a custom made module which is constantly updated. I am distributing it to other users which do not have the computer skills to update their own file (I know it's just copy paste).
I would like to know if there is a way I can code something in the Global file which checks for the latest version that is stored on a shared drive and copies and pastes in the other users computers?
Use the Project_Open event in the ThisProject module of your global.mpt file to periodically update the code in a different module in the same file (e.g. the "Main" module):
Dim LastUpdated As Date
Private Sub Project_Open(ByVal pj As Project)
' run update if more than 1 hour since last update
If Now - LastUpdated > (1 / 24) Then
With ThisProject.VBProject
.VBComponents.Remove .VBComponents("Main")
.VBComponents.Import "c:\temp\main.bas"
End With
LastUpdated = Now
End If
End Sub

Saving Template after VBA references are added

I have some code which adds the VBA references i require for using Access. (it checks if the user already has them included).
This all works fine. My problem is when i then go to close word I am prompted to save the Acronym Tools template (Where the macro that this code is stored). Is it possible to do this programtically so that is it done as soon as references are added and the user does not see it happening?
The code i use:
If Not isReferenceLoaded("Access") Then
MsgBox ("Access Object library not found, the script will now attempt to find the library for you.")
'Ensure access library is included so database actions can be done
ID.AddFromFile "C:\Program Files (x86)\Microsoft Office\Office14\MSACC.OLB"
MsgBox ("Access Object library added")
End If
If Not isReferenceLoaded("DAO") Then
MsgBox ("DAO library not found, the script will now attempt to find the library for you.")
'Ensure access library is included so database actions can be done
ID.AddFromFile "C:\Program Files (x86)\Common Files\microsoft shared\OFFICE14\ACEDAO.DLL"
MsgBox ("DAO library added")
End If
The function to see if reference is loaded:
Private Function isReferenceLoaded(referenceName As String) As Boolean
Dim xRef As Variant
For Each xRef In ThisDocument.VBProject.References
isReferenceLoaded = (xRef.Name = referenceName) Or isReferenceLoaded
Next xRef
End Function
If you don't want to save the document with the updated references (they'll be remade next time the doc is open, I guess) add to your Document object (supposedly named ThisDocument) the following subroutine:
Private Sub Document_Close()
ThisDocument.Saved = True
End Sub
This would inhibit the save-check only for ThisDocument. Add a Call ThisDocument.Save statement at the beginning, if you do want to save. However, I would count on the users to save their changes... but that's a matter of strategy, please do as you wish.
Nota Bene: Do not forget to save after adding the function: you'll lose the changes if you forget to; Word will ignore your changes because it was just instructed to do so by the function. :-)

Leaving a Project file open after retrieving it with GetObject

What is the right way to leave an MS Project file opened with GetObject() open and visible to the user after the end of a macro in a different app?
The information I found online suggests that setting the Application.UserControl property to True before the objects go out of scope should allow the user to continue using the opened file. However, for MS Project at least, the Application.UserControl property appears to be read-only. Is there a way to work around this?
A simplified example showing the problem:
Sub AddTasks()
Dim proj As Object
' Already have the file path from another part of the workflow
Set proj = GetObject("C:\projtest.mpp")
' perform some calculations and add new tasks to project
proj.Tasks.Add "additional task"
' Leave Project open and visible for the user
proj.Application.Visible = True
proj.Application.UserControl = True ' Gives "Type Mismatch" error
' without the UserControl line, runs ok, but Project closes after the end of the macro
End Sub
Instead of using GetObject, could you create an instance of the application and open the project file in the instance?
Sub AddTasks()
Dim msProj as Object
Set msProj = CreateObject("Project.Application")
msProj.FileOpen "C:\projtest.mpp"
'do stuff to project file here
msProj.Visible = True
End Sub
Something like the above (I can't test the above code because I don't have MSProject, but similar code works for MSWord)
For Project UserControl just indicates if the user started the application or not; it appears to be read-only because it is. I've not done what you're asking for with Project, although here is a similar example for Word trying to see and find running instances of Excel. Perhaps this helps a little:
can-vba-reach-across-instances-of-excel