How to delete all values in MS Project TimeScaleData - vba

I'm using the BaselineWork1 timescaledata to contain a time phased calculation of resource work on individual tasks that I perform on a weekly basis. I want to zero out the previous week's calculation before I populate it with this week's calculation. Short of creating a loop to write zeros to the timescale data for each resource on each task is there a way to do this more efficiently? Could I make the beginning date and end date equal to the project's start and end date and time scale = seconds and the value to write equal to zero? For instance:
For lngCnt1 = 1 To tskCounter.Resources.Count
tskCounter.Assignments.Item(lngCnt1).TimeScaleData(StartDate:=ActiveProject.ProjectStart, EndDate:=ActiveProject.ProjectFinish, _
Type:=pjAssignmentTimescaledBaseline1Work, _
timescalunit:=pjTimescaleMinutes, Count:=1).Item(1).Value = 0
Next lngCnt1
This doesn't seem to work as it only zeros out the baseline1 work field for the date corresponding to the project start date.

To clear time-scaled work from anything but the forecast work field, you do need to loop through every assignment on every task. However, when it comes to the individual time-scale values, you can lump these together by year to reduce the iterations required.
Sub ClearBaseline1Work()
Dim projStart As Date
Dim projEnd As Date
projStart = ActiveProject.ProjectStart
projEnd = ActiveProject.ProjectFinish
Dim tsk As Task
For Each tsk In ActiveProject.Tasks
Dim asn As Assignment
For Each asn In tsk.Assignments
Dim TSValues As TimeScaleValues
Set TSValues = asn.TimeScaleData(projStart, projEnd, pjAssignmentTimescaledBaseline1Work, pjTimescaleYears)
Dim tsv As TimeScaleValue
For Each tsv In TSValues
tsv.Clear
Next tsv
asn.Baseline1Work = 0
Next asn
tsk.Baseline1Work = 0
Next tsk
End Sub
Remember that Baseline1 work values are not automatically updated at the assignment or task level; those values need to be explicitly cleared.

Related

VBA-Extracting from MS Project Remaining Work by Assignment by Week

When looking at the possible PjAssignmentTimescaledData options (here), one that is missing that I need to extract is the Remaining Work field. Has anyone ever been able to figure out how to use VBA to extract out weekly assignments based on remaining work?
What I have is in a section of my VBA is:
ass.TimeScaleData(tsk.Start, tsk.Finish, pjAssignmentTimescaledActualWork, pjTimescaleWeeks)
but I would imagine i could replace
pjAssignmentTimescaledActualWork
with
pjAssignmentTimescaledRemainingWork
but that does not work.
Am I asking for something that just doesn't exist or looking at this whole operation in a backwards way?
Unfortunately, pjAssignmentTimescaledRemainingWork does not exist (which is annoying). To get the time phased remaining work, you need to take the value you get from pjAssignmentTimescaledWork and subtract the value you get from pjAssignmentTimescaledActualWork. Here's some sample code to get the time phased remaining work of selected tasks:
Public Sub GetTimeScaledRemainingValues()
Dim a As Assignment
Dim t As Task
Dim totalTSVs As TimeScaleValues
Dim actualTSVs As TimeScaleValues
Dim totalTSV As TimeScaleValue
Dim actualTSV As TimeScaleValue
Dim remainingValue As Double
For Each t In Application.ActiveSelection.Tasks
For Each a In t.Assignments
'get the total TSV values and store in a variable
Set totalTSVs = a.TimeScaleData(t.Start, t.Finish, pjAssignmentTimescaledWork, pjTimescaleWeeks)
'get the actual TSV values and store in a variable
Set actualTSVs = a.TimeScaleData(t.Start, t.Finish, pjAssignmentTimescaledActualWork, pjTimescaleWeeks)
'Loop through the total TSVs and try to find and substract the actual values
For Each totalTSV In totalTSVs
'Use this loop to find the actual TSV that has the same start date as the total TSV value we are currently looking at. These values will cover the same period
For Each actualTSV In actualTSVs
If actualTSV.StartDate = totalTSV.StartDate Then
'If the actual value is zero the property returns an empty string, so we have to check for this because we cannot subtract an empty string from a number, it will cause a VBA error.
If actualTSV.Value <> "" Then
'subtract the actual value from the total value to get the remaining
remainingValue = totalTSV.Value - actualTSV.Value
Else
remainingValue = totalTSV.Value
End If
'the Value property of TSV returns in minutes. divide by 60 to get the remaining hours
remainingValue = remainingValue / 60
Exit For
End If
Next actualTSV
'print out the remaining value information
Debug.Print "There are " & remainingValue & " remaining hours of " & a.ResourceName & " on " & t.Name & " between " & totalTSV.StartDate & " to "; totalTSV.EndDate
Next totalTSV
Next a
Next t
End Sub
Here's a sample of what my output looks like:
There are 16 remaining hours of Security Engineer on Create Security Requirements Traceability Matrix (SRTM) between 3/7/2021 to 3/14/2021

Create Sequence Number by year and number that will increase +1

I would like to edit/modify my field based on year and then the sequence number.
Field: Year - 00#
For example, a file is created this year, 2020.
So, I would like a filed that is computed by number and will increase +1.
The filed will be : 2020-001 , then 2020 - 002 and so on.
Before, I got some code from somebody to generate a sequence number.
Sub Querysave(Source As Notesuidocument, Continue As Variant)
'get total no of documents from the view
'if no documents then seq start with 1
Dim docCount
Dim viewCollection As NotesViewEntryCollection
Dim viewEntry As NotesViewEntry
Dim vNum As Long
If source.IsNewDoc Then
Set viewCollection = view.AllEntries
docCount = viewCollection.count
If doccount = 0 Then
doccount=1
Call source.FieldSetText("ReqNo","REQ" & Cstr(Format(docCount,"00000#")))
Else
Set viewEntry = viewCollection.GetLastEntry
Call source.FieldSetText("ReqNo","REQ" &Cstr(Format(doccount+1,"00000#")))
End If
End If
End Sub
Based on that code, how can I edit the "REQ" as per above to be the created year?
Thank you very much for your help.
You get the current year as string with
CStr(Year(Now))
Replace "REQ" with it.

How to iterate all rows and columns through a loop in MS project

Am working on Ms project file and currently am having trouble in below two areas
1) Now am trying to iterate all rows and columns through a loop
for ex:-
Task ResourcesName Start
products xxxx 10/3/2017
projects yyyy 11/04/2017
I can get first column value(Task) name using below code
dim var = ActiveProject.Tasks(x + 1).Name
but I need to traverse to resources name and start column and I need to store all the values in variables
2) second question is I observed that in my MPP file that for some columns names are like
Task
ResourcesName
Start etc
But, If I try to store the column values by using below code
For each oSubTasks in Activeproject.Task
dim var1 = oSubTasks.GetField(FieldNameToFieldConstant("Task"))
next
The values are like Text1,Text2 etc
My question is that how can i get the actual displayed values from MPP file columns
It appears that perhaps you are using vb.net rather than vba since you state this works:
dim var = ActiveProject.Tasks(x + 1).Name
If that is the case, then make sure you use Early Binding so you have IntelliSense (more info) when you are writing your code. That way you declare oSubTask As MSProject.Task and when you type oSubTask followed by a period you get a drop-down list of the properties and methods.
Secondly, you state that you want to get the "actual displayed values". For string fields such as task Name and Resource Names, there is no difference between what is stored and what is displayed. However, for date fields this is not the case. To get a task's Start date as a date value, use: oSubTask.Start. But to get the string representation of the date as displayed, use: oSubTask.GetField(pjTaskStart).
Here is a VBA sample:
Dim oSubTask As Task
Dim taskName As String
Dim taskRes As String
Dim taskStart As Date
Dim formattedStart As String
For Each oSubTask In ActiveProject.Tasks
taskName = oSubTask.Name
taskRes = oSubTask.ResourceNames
taskStart = oSubTask.Start
' to see how the date is displayed, use GetField
formattedStart = oSubTask.GetField(pjTaskStart)
' do something with these values
Next
This is an example how to loop through your Ms-Project tasks, and read the Task.Name and Task.Start from them (into an array).
Dim oSubTasks As Task
Dim oName(1000) As Variant
Dim oStart(1000) As Date
Dim i As Long
i = 1
For Each oSubTasks In Activeproject.Tasks
oName(i) = oSubTasks.Name
oStart(i) = oSubTasks.Start
i = i + 1
Next oSubTasks

Filtering out Area codes in Excel by VBA

need some assistance. It's been a very long time since I've done scripting/coding and really rusty now.
Issue: I have a spreadsheet(Excel Visual Basic) that contains call(s) over a month(Over 30k records). My goal is to filter out calls that have specific area codes (toll free, local calls...etc) and calculate how much they owe from calling long distance.
Additionally, this is a retirement home and the end-user(s) do not enter phone numbers correctly. I need to either strip 3-4 digits at the start of numbers..
Example: 1800-XXX-XXXX or 800-XXX-XXXX | 1605-XXX-XXXX
Here's the code I currently have, I'm lost on how to incorporate the 3-4 digits in the area and have it parse each record in Column H by the first 3-4 digits
Phone numbers are stored in Column H
Array TFL will store all the area codes I need to filter out.
Sub CleanEntry()
Dim i As Integer
Dim TFL As Variant
TFL = Array("1800", "1877")
For i = Sheet1.UsedRange.Rows.Count To 1 Step -1
If Left(Cells(i, "H"), 4) Like TFL(i) Then
Sheet1.Rows(i).EntireRow.Delete
End If
Next
End Sub
I'd personally use a regular expression for this:
Sub CleanEntry()
Dim i As Integer
Dim filter As New RegExp
filter.Pattern = "^1?(8(77|00))|605" 'Or whatever else you need to match.
For i = Sheet1.UsedRange.Rows.Count To 1 Step -1
If filter.Test(Trim$(Cells(i, "H").Value)) Then
Sheet1.Rows(i).EntireRow.Delete
End If
Next
End Sub
Note: You'll need to add a reference to Microsoft VBScript Regular Expressions 5.5.

Classic ASP check with result set changes

I hope I can explain this as I mean it!
I have an SQL query which has been formed as a View to make it easier to pull the data.
However, I have a week number column which gets the date and then calculates the week number. I have everything outputted into an FPDF document, but I need to split the cells after the week number changes, then display a total for that week number.
How would I go about checking when the week number column changes? I just can't think of a solution to this.
This is the code I have currently which doesn't work, there is a very high probability that this isn't right whatsoever.
if iCounter > 1 Then
NewSum = rs("W")
rs.moveprevious
if StrComp(NewSum,rs("W")) = 1 Then
pdf.Cell 15,5,"EOM",1,1,"C",1
else
rs.movenext
pdf.Cell 15,5,"",1,1,"C",1
End if
end if
In this scenario there are different ways to approach this, personally I've always found using Arrays a lot easier more flexible and more efficient than using the ADODB.Recordset.
Once you have a ADODB.Recordset object regardless of the approach (be it ADODB.Command, Recordset.Open() or Connection.Execute()) you can convert it to a two dimensional array using Recordset.GetRows().
Using your example I would structure your code like this;
Please take into consideration this is untested and coded from memory, I just wanted to give you the general gist of how to do this kind of computation in a Classic ASP environment.
Dim rs, data, row, rows
Dim weekno
Dim total_weekno, current_weekno
'Assuming you have instantiated your rs object
'...
'Convert to an Array variable (data)
If Not rs.EOF Then data = rs.GetRows()
'Close and release Recordset from memory
Call rs.Close()
Set rs = Nothing
If IsArray(data) Then
rows = UBound(data, 2)
'Iterate through the array
For row = 0 To rows
'Assuming weekno column is the first in your resultant columns.
weekno = data(0, row)
If weekno = current_weekno Then
'Increment our total for the current weekno by 1.
total_weekno = total_weekno + 1
Else
'Place logic for adding new row to PDF here.
'Use total_weekno to display the incremented total.
'Afterward reset total_weekno for the new current weekno.
total_weekno = 0
'Our weekno has changed so set current weekno.
current_weekno = weekno
End If
Next
End If