Networkplanning program, preview (iPad only)
Posted: Tue Apr 22, 2014 12:12 pm
This is a first draw of a networkplanning program, which i used regularly on PC.
The program uses the 'critical path' method, with the 'activity on node' mode.
A project plan is 'drawn' on the screen, the screen highlighting a part of a large worksheet.
For further info, use the 'help' button in the app,
for theory behind networkplanning : internet.
This version has limited capabilities. Functions that i may (or may not) incorporate in future
versions are:
- mapping of time schedule on a calendar
- a 'printable' project report (to file)
- a Gannt chart output on screen, perhaps 'printable' to file
- resources and resource loading (but no resource levelling)
- real-time monitoring of a project
and perhaps other features that come up.
As i'm not a dropbox user, i will upload one example project file wich must be placed in the directory where the program resides. For filename i suggest "itproject.prj". It can be loaded under the given name using the menu. the extension ".prj" is mandatory.
The program uses the 'critical path' method, with the 'activity on node' mode.
A project plan is 'drawn' on the screen, the screen highlighting a part of a large worksheet.
For further info, use the 'help' button in the app,
for theory behind networkplanning : internet.
This version has limited capabilities. Functions that i may (or may not) incorporate in future
versions are:
- mapping of time schedule on a calendar
- a 'printable' project report (to file)
- a Gannt chart output on screen, perhaps 'printable' to file
- resources and resource loading (but no resource levelling)
- real-time monitoring of a project
and perhaps other features that come up.
As i'm not a dropbox user, i will upload one example project file wich must be placed in the directory where the program resides. For filename i suggest "itproject.prj". It can be loaded under the given name using the menu. the extension ".prj" is mandatory.
Code: Select all
' PERT planner/monitor, version 0.2, april 2014
' by Henk Overtoom
'
' kalender mapping
' Gannt chart
' printable overzicht
' real-time monitor
' check calc en save flag plaatsen
' bij saven : check of new of load project (moet kunnen saven)
'
option base 1
maxbox=50 ! dim box(maxbox,9) ! nbox=0
maxlink=2*maxbox ! dim link(maxlink,3) ! nlink=0
dim task$(maxbox,2)
gosub init_prog ! menu() ! calc()
loop: ! task=muis()
if task=1 then disp_descr(hit_box(xo,yo))
if task=2 then task_data(hit_box(xo,yo)) ' add/edit/del task
if task=3 then
hit1=hit_box(xo,yo) ! hit2=hit_box(xe,ye)
if not hit1 then ' drag screen
trans(xe-xo,ye-yo) ! refresh()
end if
if hit1 and (hit1=hit2 or not hit2) then ' drag task
box(hit1,2)+=(xe-xo) ! box(hit1,3)+=(ye-yo)
refresh()
end if
if hit1 and hit2 and hit1<>hit2 then ' predecessor link
if nlink=0 then labmain1
k=hit_link(hit2,hit1)
if k then ' edit/delete existing link
link_data(k)
else ' add a new link
labmain1:
lnr=add_link(hit2,hit1)
if lnr then ! refresh() ! cflag=1 ! end if
end if
end if
end if
if cflag and calc_flag then calc()
goto loop
end
init_prog:
option angle degrees
graphics ! graphics clear .8,.8,.8
draw color 0,0,0 ! fill color .8,.8,.8
lw=screen_width() ! lh=screen_height()
gw=3000 ! gh=3000
box_x=160 ! box_y=80 ! bx2=.box_x/2 ! by2=.box_y/2
xs=0 ! ys=0
proj_file$="file name" ! proj_name$="project name"
proj_start=0 ! proj_otime=0 ! cflag=0 ! sflag=0
button "menu" title "menu" at 20,20 size 60,40
button "help" title "help" at 100,20 size 60,40
button "calc" title "calculate" at 180,20 size 100,40
draw font size 14 ! draw color 0,0,1
draw text "auto-calc auto-save snap to grid" at lw-295,12
draw font size 20 ! draw color 0,0,0
switch "calc" state 1 at lw-280,30 ! calc_flag=1
switch "save" state 0 at lw-180,30 ! save_flag=0
switch "grid" state 1 at lw-80,30 ! grid_flag=1
return
def menu()
xt=.lw/2-150 ! yt=.lh/2-100
w_open("main menu",xt,yt,xt+300,yt+200)
button "npro" title "new/change project" at xt+10,yt+40 size 160,30
button "load" title "load project" at xt+10,yt+80 size 160,30
button "save" title "save project" at xt+10,yt+120 size 160,30
button "oke" title "close" at xt+230,yt+160 size 60,30
labmenu1:
if but("npro") then
w1_delete(xt,yt)
w_open("new/change project",xt,yt,xt+300,yt+240)
field "fname" text .proj_file$ at xt+10,yt+40 size 160,30
field "pname" text .proj_name$ at xt+10,yt+80 size 280,30
draw text "project start" at xt+10,yt+124
field "start" text .proj_start at xt+180,yt+120 size 110,30
draw text "def.overtime %" at xt+10,yt+164
field "otime" text .proj_otime at xt+180,yt+160 size 110,30
button "oke" title "ok" at xt+230,yt+200 size 60,30
labmenu2:
if fc("start") or fc("otime") then cc=1 else cc=0
cflag=cc
if fc("fname") or fc("pname") or cc then sflag=1
.proj_file$=field_text$("fname")
.proj_name$=field_text$("pname")
.proj_start=val(field_text$("start"))
.proj_otime=val(field_text$("otime"))
if not but("oke") then labmenu2
w2_delete(xt,yt) ! sflag=1 ! cflag=1 ! return
end if
if but("load") then
labmenu3: loaded=0
field "pf" text "filename?" at xt+50,yt+250 size 160,30
wait: if not field_changed("pf") then wait
pfile$=field_text$("pf") ! f$=pfile$ & ".prj"
if not file_exists(f$) then labmenu3
field "pf" delete ! .proj_file$=pfile$ ! loaded=1
file f$ input .proj_name$
file f$ input .proj_start,.proj_otime
file f$ input .xs,.ys,.nbox,.nlink
if .nbox then
for i=1 to .nbox ! for j=1 to 8
if j<3 then file f$ input .task$(i,j)
file f$ input .box(i,j)
next j ! next i
end if
if .nlink then
for i=1 to .nlink ! for j=1 to 3
file f$ input .link(i,j)
next j ! next i
end if
goto labmenu4
end if
if but("save") and .proj_file$>"" then
f$=.proj_file$ & ".prj"
if file_exists(f$) then file f$ delete
file f$ print """" & .proj_name$ & """"
file f$ print .proj_start,.proj_otime
file f$ print .xs,.ys,.nbox,.nlink
if .nbox then
for i=1 to .nbox ! for j=1 to 8
if j<3 then file f$ print """" & .task$(i,j) & """"
file f$ print .box(i,j)
next j ! next i
end if
if .nlink then
for i=1 to .nlink ! for j=1 to 3
file f$ print .link(i,j)
next j ! next i
end if
goto labmenu4
end if
if not but("oke") then labmenu1
labmenu4: w1_delete(xt,yt)
if loaded then .cflag=1
end def
def disp_descr(ti)
if ti=0 then return else flag=0
xo=x2l(.box(ti,2)) ! yo=y2l(.box(ti,3))
sprite "descr" scan xo-2,yo-2,300,40
loopdes: get touch 0 as x,y
if x>=0 then
draw text .task$(ti,2) at xo,yo-40
flag=1 ! goto loopdes
end if
if not flag then loopdes
sprite "descr" at xo-2,yo-2 ! sprite "descr" stamp
sprite "descr" delete
end def
def task_data(ti)
if ti=0 then
if .nbox=.maxbox then return
.nbox+=1 ! ti=.nbox ! tio=0
.box(ti,2)=x2g(.xo-.bx2) ! .box(ti,3)=y2g(.yo-.by2)
d1$="" ! d2$="" ! d3$="" ! d4$="0" ! d5$="0"
else
d1$=.task$(ti,1) ! d2$=.task$(ti,2) ! tio=ti
d3$=.box(ti,4) ! d4$=.box(ti,5) ! d5$=.box(ti,6)
end if
xt=.lw/2-200 ! yt=.lh/2-300 ! x1=xt+10 ! ot=.box(ti,6) ! ret=0
d6$=u2t$(.box(ti,7),ot) ! d7$=u2t$(.box(ti,8),ot)
d8$=u2t$(.box(ti,7)+.box(ti,4),ot)
d9$=u2t$(.box(ti,8)+.box(ti,4),ot)
d10$=u2t$(.box(ti,9),ot)
w_open("task data",xt,yt,xt+400,yt+480)
draw text "task id. :" at x1,yt+40
draw text "description:" at x1,yt+80
draw text "duration :" at x1,yt+120
draw text "not before :" at x1,yt+160
draw text "overtime % :" at x1,yt+200
draw text "earliest start : "& d6$ at x1,yt+240
draw text "latest start : "& d7$ at x1,yt+280
draw text "earliest end : "& d8$ at x1,yt+320
draw text "latest end : "& d9$ at x1,yt+360
draw text "slack time : "& d10$ at x1,yt+400
field "short" text d1$ at xt+160,yt+35 size 160,30
field "desc" text d2$ at xt+160,yt+75 size 230,30
field "dur" text d3$ at xt+160,yt+115 size 120,30
field "gstart" text d4$ at xt+160,yt+155 size 120,30
field "otime" text d5$ at xt+160,yt+195 size 120,30
if tio then
button "del" title "delete task" at xt+10,yt+440 size 160,30
end if
button "canc" title "cancel" at xt+200,yt+440 size 80,30
button "oke" title "ok" at xt+300,yt+440 size 80,30
do
if but("canc") then ! ret=1 ! goto labnw ! end if
if but("del") then ! task_del(tio) ! ret=1 ! goto labnw ! end if
until button_pressed("oke")
.task$(ti,1)=field_text$("short")
.task$(ti,2)=field_text$("desc")
.box(ti,6)=val(field_text$("otime"))
if fc("dur") then
.box(ti,4)=t2u(field_text$("dur"),.box(ti,6)) ! .cflag=1
end if
if fc("gstart") then
.box(ti,5)=val(field_text$("gstart")) ! .cflag=1
end if
labnw:
graphics lock ! w3_delete(xt,yt) ! refresh() ! graphics unlock
if ret then return
disp_box(ti)
end def
def task_del(ti)
dim lt(.maxlink) ! nsuc=0
for i=1 to .nlink
if .link(i,2)=ti then ! nsuc+=1 ! lt(nsuc)=.link(i,1) ! end if
next i
if nsuc then
for k=1 to nsuc
for i=1 to .nlink
if .link(i,1)=ti then
.nlink+=1 ! .link(.nlink,3)=.link(i,3)
.link(.nlink,1)=lt(k) ! .link(.nlink,2)=.link(i,2)
end if
next i
next k
end if
if .nlink=0 then labdel1
for i=1 to .nlink
if .link(i,1)=ti or .link(i,2)=ti then
for k=i+1 to .nlink
for j=1 to 3 ! .link(k-1,j)=.link(k,j) ! next j
next k ! i-=1 ! .nlink-=1
end if
next i
labdel1:
if .nbox>1 and ti<.nbox then
for i=ti+1 to .nbox ! for j=1 to 9
.box(i-1,j)=.box(i,j)
if j<3 then .task$(i-1,j)=.task$(i,j)
next j ! next i
end if
for j=1 to 9 ! .box(.nbox,j)=0 ! next j
.task$(.nbox,1)="" ! .task$(.nbox,2)=""
.nbox-=1
for i=1 to .nlink ! for j=1 to 2
if .link(i,j)>ti then .link(i,j)-=1
next j ! next i
sflag=1 ! cflag=1
end def
def link_data(k)
suc=.link(k,1) ! pred=.link(k,2) ! lag$=u2t$(.link(k,3),0)
xt=.lw/2-180 ! yt=.lh/2-80 ! ret=0
w_open("predecessor link",xt,yt,xt+360,yt+190)
draw text "sucessor : " & .task$(suc,1) at xt+10,yt+40
draw text "predecessor : " & .task$(pred,1) at xt+10,yt+70
draw text "lag time : " at xt+10,yt+110
field "lag" text lag$ at xt+180,yt+105 size 110,30
button "del" title "delete link" at xt+10,yt+150 size 120,30
button "oke" title "ok" at xt+270,yt+150 size 80,30
lablink1:
if fc("lag") then
.link(k,3)=t2u(field_text$("lag"),0) ! .cflag=1
end if
if but("del") then ! del_link(k) ! goto lablink2 ! end if
if but("oke") then lablink2
goto lablink1
lablink2: w4_delete(xt,yt) ! refresh()
end def
def add_link(suc,pred)
if .nlink=.maxlink then ! add_link=0 ! return ! end if
.nlink+=1 ! .link(.nlink,1)=suc ! .link(.nlink,2)=pred
.calc=1 ! add_link=.nlink
end def
def draw_link(lnr)
draw size 1 ! bo=.link(lnr,2) ! be=.link(lnr,1)
if .box(bo,9)=0 and .box(be,9)=0 then
draw size 2 ! draw color 1,0,0
end if
if .link(lnr,3) then ! draw dash 5 ! draw size 2 ! end if
xo=x2l(.box(bo,2))+.box_x ! yo=y2l(.box(bo,3))+.by2
xe=x2l(.box(be,2)) ! ye=y2l(.box(be,3))+.by2
draw line xo,yo to xe,ye
draw color 0,0,0 ! draw size 1 ! draw dash 0
end def
def hit_link(hit2,hit1)
hit_link=0
for i=1 to .nlink
if hit2=.link(i,1) and hit1=.link(i,2) then
hit_link=i ! break
end if
next i
end def
def del_link(k)
if .nlink=0 then return else .cflag=1
for i=k+1 to .nlink ! for j=1 to 3
.link(i-1,j)=.link(i,j)
next j ! next i ! .nlink-=1
end def
def disp_box(i)
x=x2l(.box(i,2)) ! y=y2l(.box(i,3)) ! draw size 2
fill rect x,y to x+.box_x,y+.box_y
draw rect x,y to x+.box_x,y+.box_y ! y1=y+.box_y-22
draw line x,y+20 to x+.box_x,y+20 ! draw size 1
draw line x,y1 to x+.box_x,y1
x1=x+.box_x/2 ! draw line x1,y1 to x1,y+.box_y
draw font size 18 !
if .box(i,9)=0 then draw color 1,0,0 else draw color 0,0,.8
w$=.task$(i,1) ! if len(w$)>14 then w$=left$(w$,14)
draw text w$ at x+5,y
draw font size 15 ! draw color 0,0,0
draw text pr$(.box(i,7)) at x+3,y1+3
draw text pr$(.box(i,4)) at x1+3,y1+3
draw text "slip : " & pr$(.box(i,9)) at x+3,y1-18
draw font size 20
end def
def pr$(tt)
w$=u2t$(floor(10*tt)/10,0)
if len(w$)>8 then w$=left$(w$,8)
pr$=w$
end def
def refresh()
graphics lock ! graphics clear .8,.8,.8
for i=1 to .nlink ! draw_link(i) ! next i
for i=1 to .nbox
xo=x2l(.box(i,2)) ! xe=xo+.box_x
yo=y2l(.box(i,3)) ! ye=yo+.box_y
if xo>.lw or xe<0 or yo>.lh or ye<0 then
.box(i,1)=0 ! continue
end if
.box(i,1)=1 ! disp_box(i)
next i
draw font size 14 ! draw color 0,0,1
draw text "auto-calc auto-save snap to grid" at .lw-295,12
draw font size 20 ! draw color 0,0,0
graphics unlock
end def
def hit_box(x,y)
hit_box=0 ! if .nbox=0 then return
for i=1 to .nbox
xo=x2l(.box(i,2)) ! xe=xo+.box_x
yo=y2l(.box(i,3)) ! ye=yo+.box_y
if x>xo and x<xe and y>yo and y<ye then
hit_box=i ! break
end if
next i
end def
def x2g(x)=x+.xs ! def y2g(y)=y+.ys
def x2l(x)=x-.xs ! def y2l(y)=y-.ys
def trans(dx,dy)
.xs-=dx ! .xs=max(.xs,0) ! .xs=min(.xs,.gw-.lw)
.ys-=dy ! .ys=max(.ys,0) ! .ys=min(.ys,.gh-.lh)
end def
def muis()
muis=0
if switch_changed("calc") then .calc_flag=switch_state("calc")
if switch_changed("save") then
.save_flag=switch_state("save") ! return
end if
if switch_changed("grid") then
.grid_flag=switch_state("grid") ! return
end if
lab1: get touch 0 as .xo,.yo
if but("menu") then ! menu() ! return ! end if
if but("help") then ! intro() ! return ! end if
if but("calc") or (cflag and .calc_flag) then
calc() ! return
end if
if .xo=-1 then lab1 else pause .1
if .grid_flag then ! .xo=snap(.xo) ! .yo=snap(.yo) ! end if
lab2: get touch 0 as x,y
if x>=0 then
if abs(x-.xo)>8 or abs(y-.yo)>8 then
sleep=1 ! .xe=x ! .ye=y
end if
if .grid_flag then ! .xe=snap(x) ! .ye=snap(y) ! end if
goto lab2
end if
if sleep then ! sleep=0 ! muis=3 ! return ! end if
timer reset
lab3: get touch 0 as x,y
if x>=0 then ! muis=2 ! return ! end if
if timer()<300 then lab3
muis=1 ! return
end def
def calc()
if .nbox=0 then return
dim ee(.nbox),le(.nbox)
pred_sort(.nlink,.link,1) ! proj_end=0 ! .cflag=0
for i=1 to .nbox
.box(i,7)=max(.proj_start,.box(i,5))
ee(i)=.box(i,7)+.box(i,4) ! proj_end=max(proj_end,ee(i))
next i
if .nlink then
for i=1 to .nlink
suc=.link(i,1) ! pred=.link(i,2) ! lag=.link(i,3)
.box(suc,7)=max(.box(suc,7),ee(pred)+lag)
ee(suc)=.box(suc,7)+.box(suc,4)
proj_end=max(proj_end,ee(suc))
next i
end if
pred_sort(.nlink,.link,2)
for i=1 to .nbox
le(i)=proj_end ! .box(i,8)=le(i)-.box(i,4)
.box(i,9)=.box(i,8)-.box(i,7)
next i
if .nlink then
for i=1 to .nlink
suc=.link(i,1) ! pred=.link(i,2) ! lag=.link(i,3)
le(pred)=min(le(pred),.box(suc,8)-lag)
.box(pred,8)=le(pred)-.box(pred,4)
.box(pred,9)=.box(pred,8)-.box(pred,7)
next i
end if
refresh()
end def
def pred_sort(nl,pa(,),d)
if nl<2 then return
if d=1 then ! k1=2 ! k2=1 ! else ! k1=1 ! k2=2 ! end if
for i=1 to nl
labpr:
for j=i+1 to nl
if pa(i,k1)=pa(j,k2) then
for k=1 to 3
temp=pa(i,k) ! pa(i,k)=pa(j,k) ! pa(j,k)=temp
next k
goto labpr
end if
next j
next i
end def
def t2u(t$,ot)
ot=min(ot,200)
lt=len(t$) ! t=0 ! fac8_24=8+.08*ot
u=val(t$) ! if u<0 then tek=-1 else tek=1 ! u*=tek
pos=instr(t$,"d")
if pos>=0 then
t+=fac8_24*u
t$=right$(t$,lt-pos)
u=val(t$) ! lt=len(t$)
end if
pos=instr(t$,"h")
if pos>=0 then
t+=u
t$=right$(t$,lt-pos)
u=val(t$)
end if
pos=instr(t$,"m")
if pos>=0 then t+=u/60
if t=0 then t=u
t*=tek ! t2u=t
end def
def u2t$(u,ot)
ot=min(ot,200)
if u<0 then tek=-1 else tek=1 ! u*=tek
fac8_24=8+.08*ot
f=u/fac8_24 ! d=floor(f) ! r=u-d*fac8_24
h=floor(r) ! m=60*(r-h)
if tek<0 then t$="-" else t$=""
if d then t$=t$ & d & "d"
if h then t$=t$ & h & "h"
if m then t$=t$ & m & "m"
if len(t$)=0 then u2t$="0" else u2t$=t$
end def
def w_open(title$,xtop,ytop,xbot,ybot)
wid=xbot-xtop ! hgt=ybot-ytop
sprite "task" scan xtop-2,ytop-2,wid+4,hgt+4
r=10 ! draw size 4 ! fs=font_size()
graphics lock
draw color 0,0,0 ! draw size 4
draw circle xtop,ytop to xtop+20,ytop+20
draw circle xbot-20,ytop to xbot,ytop+20
draw circle xtop,ybot-20 to xtop+20,ybot
draw circle xbot-20,ybot-20 to xbot,ybot
draw line xtop+r,ytop to xbot-r,ytop
draw line xtop+r,ybot to xbot-r,ybot
draw line xtop,ytop+r to xtop,ybot-r
draw line xbot,ytop+r to xbot,ybot-r
fill rect xtop+r,ytop+2 to xbot-r,ybot-2
fill rect xtop+2,ytop+r to xbot-2,ybot-r
if title$<>"" then
l=(xbot-xtop-.6*fs*len(title$))/2
draw line xtop,ytop+24 to xbot,ytop+24
draw color 0,0,1
draw text title$ at xtop+l,ytop+60/fs
draw color 0,0,0
end if
graphics unlock
end def
def w1_delete(x,y)
button "npro" delete ! button "load" delete
button "save" delete ! button "oke" delete
sprite "task" at x-2,y-2 ! sprite "task" stamp
sprite "task" delete
end def
def w2_delete(x,y)
field "fname" delete ! field "pname" delete
field "start" delete ! field "otime" delete
button "oke" delete
sprite "task" at x-2,y-2 ! sprite "task" stamp
sprite "task" delete
end def
def w3_delete(x,y)
field "short" delete ! field "desc" delete
field "dur" delete ! field "gstart" delete
field "otime" delete ! button "del" delete
button "canc" delete ! button "oke" delete
sprite "task" at x-2,y-2 ! sprite "task" stamp
sprite "task" delete
end def
def w4_delete(x,y)
field "lag" delete
button "del" delete ! button "oke" delete
sprite "task" at x-2,y-2 ! sprite "task" stamp
sprite "task" delete
end def
def date$() ' gives date as m$-dd-yyyy
dim month$(12) ' (option base 1)
for i=1 to 12 ! read month$(i) ! next i
data "yan","febr","march","april","may","june"
data "july","aug","sept","oct","nov","dec"
yy=current_year()
mm=current_month()
dd=current_date()
date$=month$(mm) & "-" & dd & "-" & yy
end def
def snap(x) = 20*int(x/20)
def but(a$) = button_pressed(a$)
def fc(a$) = field_changed(a$)
def intro()
w_open("Short manual networkplanning",50,100,.lw-50,.lh-50)
graphics lock
drt("* for theory on networkplanning: search internet")
drt("* this program uses the CPM method, activity-on-node")
drt("* activities are identical to the word 'task'")
drt("* a project plan may be saved and loaded via the menu")
drt("* double-tap on an empty place of the screen to create")
drt.y-=20 ! drt(" a new task on that spot")
drt("* double-tap on an existing task to edit/delete it")
drt("* drag from one task to another to create a new link")
drt("* drag over an existing link to edit/delete that link")
drt("* drag an empty spot on the screen to move the network")
drt("* when the 'auto-calc' switch is on, the network cal-")
drt.y-=20 ! drt(" culation is done whenever needed")
drt("* the earliest possible start of a task is shown")
drt.y-=20 ! drt(" bottom left, the duration bottom right")
drt("* a link with a lag time>0 has a dashed line")
drt("* times are shown in ..d.h.m (day,hour.minute) format,")
drt.y-=20 ! drt(" all calculations are done in hours")
drt("* 'open-ended' networks are treated correctly")
drt("* when a task is deleted, new links are generated to")
drt.y-=20 ! drt(" preserve the network logic")
button "go" title "ok" at .lw/2-50,.lh-110 size 100,40
graphics unlock
labin: if not but("go") then labin
sprite "task" at 48,98 ! sprite "task" stamp
sprite "task" delete ! button "go" delete
drt.y=0
end def
def drt(a$)
if not y then y=150
draw text a$ at 60,y
y+=40
end def
' box-i,1 : yes/no in viewport
' box-i,2 : globale x-coordinaat linkerbovenhoek
' box-i,3 : idem y-coordinaat
' box-i,4 : duration
' box-i,5 : given start (not before ...)
' box-i,6 : overtime %
' box-i,7 : earliest start
' box-i,8 : latest start
' box-i,9 : slack time
' link-i,1 : successor task
' link-i,2 : predecessor task
' link-i,3 : lag