MSP 2000/2002/2003 VBA API Bug - View and Table switching

R

Robert Emmery

Bug #1 - API parameter values are language specifi
-----
There seems to be a serious limitation in all MSP versions that prohibits
developers from writing language independent code that references views an
tables. The problem is that MSP API requires English strings such as "Gantt
View" and "Entry" to be passed as parameter values when switching between
various views and tables. These stings however cannot be retrieved anywhere
in the system which forces the programmers to localize their code. I would
think that the need to localize code in most cases indicates a serious
flaw in the design of either the language or the API. UI localization is
something quite different. In MSP VBA, if your code references views an
tables the way that MSP API suggests, your code would not run in a French
version of MSP since the French application expects strings "Diagramme de
Gantt" and "Entree" instead of "Gantt Chart" and "Entry"

ApplyView "Gantt View" ' causes error dialog in French MS

Bug #2 - Application.EditTable and other methods in this category require
existing object name to create a new tabl
------
One way to avoid bug #1 would be to create your own views an
tables and forget about using the default ones. As it turns out, thi
creates the same language dependency problem since view and table creatio
APIs require that you pass names of the existing views or tables

' The following line causes error dialog in French MS
TableEdit Name:="Entry", TaskTable:=False, Create:=True,
NewName:="MyEntryTable

' The following line plainly does not work, in spite of contradictin
' API specificatio
TableEdit Name:="MyEntryTable", TaskTable:=False, Create:=Tru

Bug #3 - ViewEdit's Screen parameter doesn't seem to be used at al
-------
A possible workaround for Bug #2 could be to pick the first table name from
the collection of table names (Application.ActiveProject.ResourceTableList
and the first view name from the collection of view names
(Application.ActiveProject.ResourceViewList). This however will not work fo
certain views as the "Screen" parameter in ViewEdit doesn't seem to be used
at all. Instead the value appears to be taken from the view that you are
copying from. To see the problem, try creating your own Resource Usage view
that has the same look and feel as the default "Resource Usage", but instea
of specifying the source view name "Resource Usage" use the first view you
get from the Application.ActiveProject.ResourceViewList. The view you ar
creating should have the screen type PjViewScreen.pjResourceUsage which
renders the screen in two halves, left with the table, and right with th
graphical data. Basically, the following code will not do the right thing in
any of the MSP versions

'disable dialog
MSProject.DisplayAlerts = Fals
'copy views from global to activ
Application.OrganizerMoveItem Type:=pjViews, FileName:="Global.mpt",
TofileName:=ActiveProject.FullNam
'enable dialog
MSProject.DisplayAlerts = Tru

templateTableName = Application.ActiveProject.ResourceTableList.Item(1
newTableName = "MyTable
templateViewName = Application.ActiveProject.ResourceViewList.Item(1
newViewName = "MyResUsageView

TableEdit Name:=templateTableName, TaskTable:=False,
Create:=True, NewName:=newTableNam
ViewEditSingle Name:=templateViewName, NewName:=newViewName,
Create:=True, Screen:=PjViewScreen.pjResourceUsage,
ShowInMenu:=True, Table:=newTableNam
ViewApply newViewNam

The screen type in the VieEditSingle line is taken from templateViewName's object and not the "Screen" parameter

There is actually a workaround for bug #3 in MSP2002 and MSP2003 thanks to their extended object model which now makes ViewsSingle and Table objects collections accessible to programmers. With these objects available to the programmers, we can now search for a view in the list that has the screen type pjViewScreen.pjResourceUsage. The following code will do what we want, but only in MSP2002 and higher

Sub setupOracleResourceUsageView()

MSProject.DisplayAlerts = False
Application.OrganizerMoveItem Type:=pjViews, FileName:="Global.mpt", _
TofileName:=ActiveProject.FullName
MSProject.DisplayAlerts = True

' Get any task table name
templateTableName = ActiveProject.ResourceTableList.Item(1)
' Get first resource usage view and use it as a view template
For Each viewObject In ActiveProject.ViewsSingle
If viewObject.Screen = pjResourceUsage Then
templateViewName = viewObject.Name
GoTo endLoop
End If
Next viewObject

endLoop:

newTableName = "RobsUsageTable"
newViewName = "RobsUsageView"

If templateTableName <> Empty And templateViewName <> Empty Then
' First delete the table and view
' To be implemented...


' Create table
TableEdit Name:=templateTableName, TaskTable:=False, Create:=True, _
NewName:=newTableName

' Create view
ViewEditSingle Name:=templateViewName, NewName:=newViewName, _
Create:=True, Screen:=PjViewScreen.pjResourceUsage, _
ShowInMenu:=True, Table:=newTableName

' Switch to new view
ViewApply newViewName
Else
' Error. Was not able to find template view or table (should no really
' happen)
End If

End Sub
 
R

Rod Gill

Hi,

For earlier versions, the work around is to manually create a view and table
with a known name. This can then be referred to in your code. Store these
new views and tables in the Global file and they will work for all your
projects.

--
For VBA posts, please use the public.project.developer group.
For any version of Project use public.project
For any version of Project Server use public. project.server

Rod Gill
Project MVP
For Microsoft Project companion projects, best practices and Project VBA
development services
visit www.projectlearning.com/
Robert Emmery said:
Bug #1 - API parameter values are language specific
------
There seems to be a serious limitation in all MSP versions that prohibits
developers from writing language independent code that references views and
tables. The problem is that MSP API requires English strings such as "Gantt
View" and "Entry" to be passed as parameter values when switching between
various views and tables. These stings however cannot be retrieved anywhere
in the system which forces the programmers to localize their code. I would
think that the need to localize code in most cases indicates a serious
flaw in the design of either the language or the API. UI localization is
something quite different. In MSP VBA, if your code references views and
tables the way that MSP API suggests, your code would not run in a French
version of MSP since the French application expects strings "Diagramme de
Gantt" and "Entree" instead of "Gantt Chart" and "Entry".

ApplyView "Gantt View" ' causes error dialog in French MSP

Bug #2 - Application.EditTable and other methods in this category require
existing object name to create a new table
-------
One way to avoid bug #1 would be to create your own views and
tables and forget about using the default ones. As it turns out, this
creates the same language dependency problem since view and table creation
APIs require that you pass names of the existing views or tables.

' The following line causes error dialog in French MSP
TableEdit Name:="Entry", TaskTable:=False, Create:=True, _
NewName:="MyEntryTable"

' The following line plainly does not work, in spite of contradicting
' API specification
TableEdit Name:="MyEntryTable", TaskTable:=False, Create:=True

Bug #3 - ViewEdit's Screen parameter doesn't seem to be used at all
--------
A possible workaround for Bug #2 could be to pick the first table name from
the collection of table names (Application.ActiveProject.ResourceTableList)
and the first view name from the collection of view names
(Application.ActiveProject.ResourceViewList). This however will not work for
certain views as the "Screen" parameter in ViewEdit doesn't seem to be used
at all. Instead the value appears to be taken from the view that you are
copying from. To see the problem, try creating your own Resource Usage view
that has the same look and feel as the default "Resource Usage", but instead
of specifying the source view name "Resource Usage" use the first view you
get from the Application.ActiveProject.ResourceViewList. The view you are
creating should have the screen type PjViewScreen.pjResourceUsage which
renders the screen in two halves, left with the table, and right with the
graphical data. Basically, the following code will not do the right thing in
any of the MSP versions:

'disable dialogs
MSProject.DisplayAlerts = False
'copy views from global to active
Application.OrganizerMoveItem Type:=pjViews, FileName:="Global.mpt", _
TofileName:=ActiveProject.FullName
'enable dialogs
MSProject.DisplayAlerts = True

templateTableName = Application.ActiveProject.ResourceTableList.Item(1)
newTableName = "MyTable"
templateViewName = Application.ActiveProject.ResourceViewList.Item(1)
newViewName = "MyResUsageView"

TableEdit Name:=templateTableName, TaskTable:=False, _
Create:=True, NewName:=newTableName
ViewEditSingle Name:=templateViewName, NewName:=newViewName, _
Create:=True, Screen:=PjViewScreen.pjResourceUsage, _
ShowInMenu:=True, Table:=newTableName
ViewApply newViewName


The screen type in the VieEditSingle line is taken from templateViewName's
object and not the "Screen" parameter.
There is actually a workaround for bug #3 in MSP2002 and MSP2003 thanks to
their extended object model which now makes ViewsSingle and Table objects
collections accessible to programmers. With these objects available to the
programmers, we can now search for a view in the list that has the screen
type pjViewScreen.pjResourceUsage. The following code will do what we want,
but only in MSP2002 and higher:
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top