Module 1 - Lesson 1 Exercises Page 1-9
3. | No, make the macro non-interactive and then use a combination of FilterEdit and FilterApply or use the SendKeys statement before the FilterApply method. |
4. | No, remove the Copies:= from the statement to make it read >> FilePrint 1. Also, changing any default settings will fix it, i.e. add the parameter Color:=True |
Module 1 - Lesson 2
"Try This: Using Declared Data" Page 1-17
1. The error "Variable Not Defined" appears - to correct the problem, change State to a public variable using Public in place of the Dim statement.
2. Local takes precedence
Module 1 - Lesson 2 Exercises Page 1-23
1. | A variable should be used. It will be declared in the General Declarations section using either the Private or Dim statement. The value will be set in the procedure where the condition is tested. While the value does not change, it is not possible to declare a constant without assigning it a value and once it is declared, it cannot be modified. |
Dim VariableName as Integer
Sub Sample()
VariableName = expression
End Sub
2. | The customer may not be using the appropriate data type for the arrays. For example, the values may be integers but the arrays are declared using the variant data type. This can significantly slow execution if very large arrays (or many variables) are involved. |
3.
Sub Sample()
MsgBox Val(InputBox("Enter number")) * 100
End Sub
4.
Sub Auto_Open()
MsgBox Now()
End Sub
Module 1 - Lesson 2 Exercises (continued)
5.
Sub StringFun()
Dim daString As String
Dim vFirstWord, vMiddleWord, vLastWord As String
Dim v3rdSpace, vSpacePos1, vSpacePos2 As Integer
daString = InputBox("Enter 5 words separated by spaces")
'Finds position of 3rd space and deletes everything to the right
v3rdSpace = InStr(InStr(InStr(1, daString, " ") + 1, _
daString, " ") + 1, daString, " ")
daString = Trim(Left(daString, v3rdSpace - 1))
'Determines positions of the two spaces between the three words
vSpacePos1 = InStr(1, daString, " ")
vSpacePos2 = InStr(vSpacePos1 + 1, daString, " ")
'Pulls out words
vFirstWord = Left(daString, vSpacePos1 - 1)
vLastWord = Right(daString, Len(daString) - vSpacePos2)
vMiddleWord = Mid(daString, vSpacePos1 + 1, _
vSpacePos2 - vSpacePos1 - 1)
'Concatenates message with linefeeds
MsgBox vFirstWord & Chr(10) & vMiddleWord & Chr(10) & vLastWord
End Sub
Module 1 - Lesson 3 Exercises Page 1-30
1.
Sub GenerateArrayValues()
Dim MyArray(1 To 2, 1 To 10) 'Array declaration
Dim Counter As Integer 'Counts the number of times a value is assigned to the array
Dim RandNum As Integer 'Stores the random number
Dim Used As Boolean 'Indicates if number has already been assigned to the array
Dim i As Integer 'Used as a loop counter in various areas of the procedure
Counter = 0
Randomize 'Tells VB to use system timer for seed value when generating
' random numbers
' This part of the procedure generates the random numbers and assigns
' them to the array
Do While Counter < 10 'Loop until all values are assigned
Used = False
RandNum = Int((10 - 1 + 1) * Rnd + 1) 'Generates random number between 1-10 (see Help)
If Counter = 0 Then 'If first time, assigns number to first element
MyArray(1, 1) = RandNum ' and increments counter
Counter = Counter + 1
Else 'If it's not the first time through the loop
For i = 1 To Counter 'For every number in the array
If RandNum = MyArray(1, i) Then 'Compare new number to numbers already assigned
Used = True 'If found, then set the flag and exit the loop
Exit For
End If
Next i
If Used = False Then 'If the number does not exist in the array
MyArray(1, Counter + 1) = RandNum ' then assign it to the next element
Counter = Counter + 1 ' and increment the counter
End If
End If
Loop
' This part of the procedure assigns the strings to the array based
' on the value
For i = 1 To 10 'For each number in the array
Select Case MyArray(1, i) ' compare the value and assign the appropriate
Case Is < 5 ' string value
MyArray(2, i) = "Smaller"
Case Is = 5
MyArray(2, i) = "Equal"
Case Else
MyArray(2, i) = "Bigger"
End Select
Next i
' The part of the procedure displays the values that are even
For i = 1 To 10 'For each number array, see if the remainder
If MyArray(1, i) Mod 2 = 0 Then ' is zero when divided by two (= even number)
MsgBox "Number = " & MyArray(1, i) & " String = " & MyArray(2, i)
End If
Next i
End Sub
Module 1 - Lesson 4 Exercises Page 1-34
1. Only one difference: function will return a value.
2. He/she can use the IsMissing function within an If statement to check to see if the argument has been passed to the function. IsMissing will return True if no argument was passed and will return False if it was.
3.
Function MyPoser(pNumber)
MyPower = pNumber ^ .05 * 6
End Function
Module 1 - Lesson 5 Exercises Page 1-43
1. Yes, highlight the variable to watch in the code pane of the Debug window, press the Instant Watch Tool on the Visual Basic toolbar and choose the Add button. Or choose Tools Add Watch.
2.
Sub GetFile()
Dim goodFile As Boolean
On Error GoTo errorHandler
Do
goodFile = True
fileName = InputBox(prompt:="Enter a filename")
if fileName = "" Then Exit Sub
FileOpen fileName
If goodFile Then Exit Sub
Loop
errorHandler:
goodFile = False
Msg = "The file, " & fileName & ", is either already open or not available."
x = Application.Message(Message:=Msg, Type:=pjYesNo, _
YesText:="Try Again", NoText:="Exit Procedure")
If x = True Then Resume Next
End Sub
Module 2 - Lesson 1
Exercise2: (MoveRect) Page 2-6
Sub MoveRect()
FileSave
For i = 1 To 5
SelectCellRight 2
SelectCellDown 2
SelectCellLeft 2
SelectCellUp 2
Next i
FileClose
End Sub
Exercise: (ApplyAView) Page 2-10
Sub ApplyAView()
test = False
myView = InputBox("Enter a View to display: ")
For Each item In ActiveProject.TaskViewList
If LCase(item) = LCase(myView) Then
ViewApply Name:=myView
test = True
End If
Next item
If test = False Then MsgBox "View Does not exist"
End Sub
Module 2 - Lesson 2
Exercise1: (TaskTraverse) Page 2-16
Sub TaskTraverse()
For Each t In ActiveProject.Tasks
If t.Duration > 5 * 480 Then t.Duration = t.Duration * 0.9
If t.Summary Then
If t.OutlineChildren > 5 Then t.OutlineHideSubtasks
End If
Next t
End Sub
Module 2 - Lesson 2 (continued)
Exercise2: (TaskLink) Page 2-16
Sub TaskLink()
For Each t In ActiveProject.Tasks
i = 0
If t.Summary Then
If t.OutlineChildren > 1 Then
idTmp1 = t.ID + 1
idTmp2 = t.ID + 2
ActiveProject.Tasks(idTmp2).LinkPredecessors _
Tasks:=ActiveProject.Tasks(idTmp1)
End If
End If
Next t
End Sub
Exercise1: Page 2-18
Sub ResMaxUnits()
RName = InputBox("Enter the name of the resource to edit")
RMax = InputBox("The Max Units for " & RName & " is " & _
ActiveProject.Resources(RName).GetField(FieldID:=pjMaxUnits) _
& " Do you want to Change it? Y/N")
If RMax = "y" Then
ActiveProject.Resources(RName).MaxUnits = _
InputBox("Enter new value")
End If
End Sub
Exercise1: (AssignWork1) Page 2-20
Sub AssignWork1()
RName = InputBox("Enter the name of the resourse to remove work from:")
For Each t In ActiveProject.Tasks
For Each r In t.Assignments
If r.ResourceName = RName Then r.Work = r.Work - 60
Next r
Next t
End Sub
Module 2 - Lesson 2 (continued)
Exercise2: (AssignWork2) Page 2-20
Sub AssignWork2()
For Each t In ActiveProject.Tasks
For Each r In t.Assignments
If r.ResourceName = t.Text1 Then r.Work = r.Work + r.Work * 0.2
Next r
Next t
End Sub
Module 2 - Lesson 3
Exercise1: (CalRangeSet) Page 2-26
Sub CalRangeSet()
DRangeStart = InputBox("Enter the Start date of the break")
DRangeFinish = InputBox("Enter the Finish date of the break")
ActiveProject.BaseCalendars("Standard") _
.Period(DRangeStart, DRangeFinish).Working = False
End Sub
Exercise2: (CalTaskMove) Page 2-26
Sub CalTaskMove()
Dim newTime As String
newTime = InputBox("Enter the a duration")
x = ActiveProject.Tasks(ActiveCell.Task.ID - 1).Start
ActiveCell.Task.Start = DateAdd(x, newTime)
End Sub
Module 3 - Lesson 1 Exercises Page 3-18
1.
Sub M3L1E1()
Dim MyErr As Integer, msg As String
On Error Resume Next
AppActivate "Microsoft Project"
MyErr = Err
On Error GoTo 0
If MyErr > 0 Then
msg = "Make sure Microsoft Project is running " & _
"before using this macro."
MsgBox msg
End If
End Sub
2.
Sub M3L1E2()
Dim MyErr As Integer, response As Integer
On Error Resume Next
AppActivate "Microsoft Excel"
MyErr = Err
On Error GoTo 0
If MyErr > 0 Then
msg = "Excel is not running. Do you want to start it?"
response = MsgBox(msg, vbYesNo)
If response = vbYes Then
AppExecute command:="Excel" 'or use Shell with full path
Else
End 'don't need this; macro ends anyway
End If
End If
End Sub
Module 3 - Lesson 1 Exercises (continued)
3.
Sub M3L1E3()
Dim msg As String, response As String, MyErr As Integer
On Error Resume Next
AppActivate "Microsoft Excel"
MyErr = Err
On Error GoTo 0
If MyErr > 0 Then
AppExecute command:="Excel" 'or use Shell with full path
Else
AppActivate "Microsoft Project" 'so next msg can be seen
msg = "Excel is already running. You can switch to it, " & _
"or start a new instance."
response = Message(msg, pjYesNoCancel, "Current", "New")
If response = True Then 'Current (Yes) button
AppActivate "Microsoft Excel"
ElseIf response = False Then 'New (No) button
Shell "D:\Excel5\Excel.exe", 3 'Shell new instance
Else 'Cancel button
End 'don't need this; macro ends anyway
End If
End If
End Sub
4.
Sub M3L1E4()
Dim MyErr As Integer
On Error Resume Next
AppActivate "Microsoft Excel"
MyErr = Err
On Error GoTo 0
If MyErr = 0 Then
SendKeys "%{F4}" 'Send Alt-F4 to close it
End If
End Sub
Module 3 - Lesson 2 Exercises Page 3-23
1.
Sub M3L2E1()
Dim s As String
s = InputBox("Enter some text.")
Shell "Notepad.exe", 3
SendKeys s
End Sub
2.
Sub M3L2E2()
ViewApply Name:="&Gantt Chart"
SelectTaskColumn Column:="Name"
EditCopy
Shell "NotePad.exe", 3
SendKeys "%EP"
End Sub
3.
Sub M3L2E3()
Dim T As Object
Shell "NotePad.exe", 3
For Each T In ActiveProject.Tasks
SendKeys T.Name
SendKeys "{Enter}"
Next
End Sub
4.
Sub M3L2E4()
SendKeys "If Then"
SendKeys "{Enter 2}"
SendKeys "End If"
SendKeys "{Up 2}"
SendKeys "{Left 3}"
End Sub
Module 3 - Lesson 3 Exercises Page 3-49
1.
Step (13): In the Form_Load, cmdPrevious_Click, and cmdNext_Click procedures, replace the two lines
lblTaskName = oTask.Name
txtDuration = oTask.GetField(29)
with the following lines:
If oTask Is Nothing Then
lblTaskName = ""
txtDuration = ""
Else
lblTaskName = oTask.Name
txtDuration = oTask.GetField(29)
End If
And the new cmdUpdate_Click procedure is:
Sub cmdUpdate_Click ()
If oTask Is Nothing Then
MsgBox "Task is blank"
txtDuration = ""
Else
oTask.Duration = txtDuration
End If
End Sub
Step (14): A command button was created, labeled "GoTo", and its Name property was changed to cmdGoto. The click procedure is shown below:
Sub cmdGoto_Click ()
Dim N As Integer
On Error Resume Next
N = InputBox("Enter task id")
Set oTask = oMSP.activeproject.tasks(N)
If Err > 0 Then
MsgBox "Bad ID"
Exit Sub
End If
nTaskID = N
lblTaskID = nTaskID
If oTask Is Nothing Then
lblTaskName = ""
txtDuration = ""
Else
lblTaskName = oTask.Name
txtDuration = oTask.GetField(29)
End If
End Sub
Module 3 - Lesson 3 Exercises (continued)
2.
Sub m3l3e2()
Dim P As Object
Set P = CreateObject("MSProject.Project")
P.Tasks.Add Name:="a"
P.Tasks.Add Name:="b"
P.Tasks.Add Name:="c"
P.Tasks(2).Predecessors = 1
P.Tasks(3).Predecessors = 2
End Sub
3.
Sub M3L3E3()
Dim oMSP As Object, T As Object
Dim N As Integer, R As Integer
Set oMSP = CreateObject("MSProject.Application")
oMSP.Visible = True
AppActivate "Microsoft Project"
oMSP.FileNew
N = Sheets("Sheet1").Cells(1, 1).CurrentRegion.Rows.Count
For R = 1 To N
Set T = oMSP.ActiveProject.Tasks _
.Add(Name:=Sheets("sheet1").Cells(R, 1).Value)
T.Start = Sheets("sheet1").Cells(R, 2).Value
T.Duration = Sheets("sheet1").Cells(R, 3).Value
Next
End Sub
4. A command button named cmdClose and a listbox named List1 was created on Form1 in VB3. The code is shown below:
Sub Form_Load ()
Dim oMSP As object, oTasks As object
Dim n As Integer
Set oMSP = GetObject(, "msproject.application")
Set oTasks = oMSP.ActiveProject.Tasks
For n = 1 To oTasks.Count
If Not oTasks(n) Is Nothing Then
List1.AddItem oTasks(n).Id & " " & oTasks(n).Name
End If
Next
End Sub
Sub cmdClose_Click ()
End
End Sub
Module 3 - Lesson 3 Exercises (continued)
5. A command button named cmdClose and a listbox named List1 was created on Form1 in VB3. The code is shown below:
Sub Form_Load ()
Dim oMSP As object, oResources As object
Dim n As Integer
Set oMSP = GetObject(, "msproject.application")
Set oResources = oMSP.ActiveCell.Task.Resources
For n = 1 To oResources.Count
List1.AddItem oResources(n).Name
Next
End Sub
Sub cmdClose_Click ()
End
End Sub
6.
Sub M3L3E6()
Dim x As Object, T As Object, R As Integer
Set x = CreateObject("Excel.Application")
x.Workbooks.Add
R = 1
For Each T In ActiveProject.Tasks
If Not T Is Nothing Then
x.ActiveSheet.Cells(R, 1).Value = T.Name
x.ActiveSheet.Cells(R, 2).Value = T.GetField(29)
R = R + 1
End If
Next
x.ActiveWorkbook.Close SaveChanges:=True
x.Quit
End Sub
Module 3 - Lesson 3 Exercises (continued)
7.
Sub M3L3E7()
Dim x As Object, T As Object, s As Object
Dim R As Integer, MyErr As Integer
On Error Resume Next
AppActivate "microsoft excel"
MyErr = Err
On Error GoTo 0
If MyErr > 0 Then
AppExecute command:="Excel.exe"
AppActivate "Microsoft Excel"
End If
Set x = GetObject(, "Excel.Application")
x.WindowState = pjMaximized
x.Workbooks.Add
Set s = x.ActiveSheet
R = 1
For Each T In ActiveProject.Tasks
If Not T Is Nothing Then
s.Cells(R, 1).Value = T.Name
s.Cells(R, 2).Value = _
T.Duration / 60 / ActiveProject.HoursPerDay
R = R + 1
End If
Next
x.Charts.Add
x.ActiveChart.ChartWizard _
Source:=s.Cells(1, 1).CurrentRegion, _
PlotBy:=2, _
CategoryLabels:=1
End Sub
Module 3 - Lesson 4 Exercises Page 3-73
1. The MSProject macro:
Sub AllOneDay()
Dim T As Object
For Each T In ActiveProject.Tasks
If Not T Is Nothing Then
T.Duration = "1d"
End If
Next
End Sub
The Excel DDE macro:
Sub M3L4E1a()
Dim SystemChannel As Integer
SystemChannel = DDEInitiate("winproj", "system")
DDEExecute SystemChannel, "AllOneDay"
DDETerminate SystemChannel
End Sub
The Excel OLE macro:
Sub M3L4E1b()
Dim oMSP As Object
Set oMSP = CreateObject("MSProject.Application")
oMSP.Macro "AllOneDay"
End Sub
2. The MSProject macro:
Sub IncreaseCost(TaskID As Integer, CostChange As Currency)
Dim T As Object
Set T = ActiveProject.Tasks(TaskID)
T.FixedCost = T.FixedCost + CostChange
End Sub
The Excel macro:
Sub M3L4E2()
Dim SystemChannel As Integer
SystemChannel = DDEInitiate("winproj", "system")
DDEExecute SystemChannel, "IncreaseCost 1, 10.5"
DDETerminate SystemChannel
End Sub
Module 3 - Lesson 5 Exercises Page 3-83
1. "Microsoft Project 4.0 Project Object" and "Picture". Paste Link is not available.
2.
Sub M3L5E2()
Dim x As Object
Set x = GetObject(, "Excel.Application")
x.Range("A1:D3").Select
x.Selection.Copy
ViewApply Name:="Task Form"
EditGoTo ID:=3
ViewShowObjects
EditPaste
End Sub
3.
Sub M3L5E3()
Dim x As Object
ViewApply "Gantt Chart"
SelectAll
EditCopy
Set x = CreateObject("Word.Basic")
x.EditPaste
End Sub
Module 3 - Lesson 6 Exercises Page 3-92
1.
Sub M3L6E1()
Dim fnum As Integer
Dim otask As Object
Dim sFileName
sFileName = InputBox("Enter a path and filename")
fnum = FreeFile()
Open sFileName For Output As fnum
For Each otask In ActiveProject.Tasks
If Not otask Is Nothing Then
Write #fnum, otask.UniqueID, CStr(otask.Start)
End If
Next
Close fnum
End Sub
2.
Sub M3L6E2()
Dim fnum As Integer, otask As Object
Dim Uid As Long, Dur As String, MyErr As Integer
fnum = FreeFile()
Open "C:\M3L6E2.txt" For Input As fnum
Do Until EOF(fnum)
Input #fnum, Uid, Dur
On Error Resume Next
ActiveProject.Tasks.UniqueID(Uid).Duration = Dur
MyErr = Err
On Error GoTo 0
If MyErr > 0 Then
MsgBox "There is no task with unique id = " & Uid
End If
Loop
Close fnum
End Sub
Module 3 - Lesson 7 Exercises Page 3-100
1.
Sub M3L7E1()
Dim r As Object
For Each r In ActiveProject.Resources
If Not r Is Nothing Then
MailSend To:=r.EMailAddress, _
Subject:="Rates", _
Body:=" Standard Rate: " & r.StandardRate & Chr(10) _
& " Overtime Rate: " & r.OvertimeRate, _
IncludeDocument:=False
End If
Next
End Sub
2.
Sub M3L7E2()
Dim r As Object
For Each r In ActiveProject.Resources
If Not r Is Nothing Then
MailSend To:=r.EMailAddress, _
Subject:="Multiline Notes", _
Body:=r.GetField(pjResourceNotes), _
IncludeDocument:=False
End If
Next
End Sub
3.
Sub M3L7E3()
ViewApply "Gantt Chart"
SelectAll
MailSendProjectMail MessageType:="TaskRequest", _
Subject:="Assignments", _
Body:="Respond ASAP", _
Fields:="Resource Names", _
ShowDialog:=False
End Sub
Module 3 - Lesson 8 Exercises Page 3-115
1.
'********************************************************
'Put in the declarations section
Declare Function GetActiveWindow Lib "USER" () As Integer
Declare Sub SetWindowPos Lib "USER" _
(ByVal hWnd As Integer, _
ByVal hWndInsertAfter As Integer, _
ByVal x As Integer, ByVal Y As Integer, _
ByVal cx As Integer, ByVal cy As Integer, _
ByVal wFlags As Integer)
Global Const HWND_TOPMOST = -1
Global Const SWP_NOSIZE = &h1
Global Const SWP_NOMOVE = &h2
'********************************************************
Sub M3L8E1()
Shell "Calc.exe", 1
DoEvents 'Precaution- Give it a chance to open.
AppActivate "Calculator" 'Precaution- Make sure it's active
SetWindowPos GetActiveWindow(), _
HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE + SWP_NOSIZE
End Sub
Module 3 - Lesson 8 Exercises (continued)
2.
'********************************************************
'Put in the declarations section
Declare Function GetActiveWindow Lib "USER" () As Integer
Declare Function OpenClipboard Lib "USER" _
(ByVal hWnd As Integer) As Integer
Declare Function EmptyClipboard Lib "USER" () As Integer
Declare Function GetClipboardData Lib "USER" _
(ByVal wFormat As Integer) As Integer
Global Const CF_TEXT = 1
Declare Function CloseClipboard Lib "USER" () As Integer
Declare Function GlobalLock Lib "KERNEL" _
(ByVal hMem As Integer) As Long
Declare Function GlobalUnlock Lib "KERNEL" _
(ByVal hMem As Integer) As Integer
Declare Function lstrcpyn Lib "KERNEL" _
(ByVal lpString1 As Any, ByVal lpString2 As Any, _
ByVal nChars As Integer) As Long
'********************************************************
Sub M3L8E2()
Dim MemoryBlockId As Integer
Dim MemoryBlockAddress As Long
Dim s As String * 5 'Reserve room for "hello"
OpenClipboard GetActiveWindow()
EmptyClipboard
CloseClipboard
Do
DoEvents
OpenClipboard GetActiveWindow()
MemoryBlockId = GetClipboardData(CF_TEXT)
MemoryBlockAddress = GlobalLock(MemoryBlockId)
lstrcpyn s, MemoryBlockAddress, 6 'must specify one higher
GlobalUnlock MemoryBlockId
CloseClipboard
Loop Until s = "hello"
MsgBox "goodbye"
End Sub