Friday, November 6, 2015

facturation program to make invoice in vbs and xml

So, my new employer is a contractor

I have to present an invoice to him for my services

I am not a big fan of word or excel to handle a dynamic facturation form

So here it is in VBS using internet explorer for interface

First you have to press new invoice to create a new xml file
Then you can edit it's details in edit xml file providing the number of the invoice)
Then you can save it
The following week, you open an old invoice in edit xml, change the number, and you got a new invoice

There is a lot of unused code in there, but i keep it anyway :P

To print it, I go in facturation, display it, then copy past it in word and print
The html result is 100% width, so it will adapt to the page format

-------------------------- facturation.vbs ------------------------

'=== Ultimate dynamic web interface 2.0

'=== this script:
'=== generate dynamically a web interface to manage virtually anything
'=== control (left frame), input (middle frame), and output (bottom frame) from vbs/wsh (windows host scripts)

'=== the first version was a simple interface made by a programmer
'=== the second version have more explanations
'=== more dynamism than ever
'=== more functions to clean up main loop code
'=== easier array display coding to add stuff more easily
'=== MDB (access type database) management (creation, edition, search/edit)
'=== futur: mdb import, mdb export, sql sync, excel export

'=== by: SergeFournier(at)hotmail.com

'=== tested on windows vista 64, internet explorer 7

Set objFSO    = CreateObject("Scripting.FileSystemObject")
Set objshe    = CreateObject("WScript.Shell")
Set objNet    = CreateObject("WScript.Network")

Const hkcr = &H80000000 'HKEY_CLASSES_ROOT
Const HKCU = &H80000001 'HKEY_CURRENT_USER
Const hklm = &H80000002 'HKEY_LOCAL_MACHINE
Const hku  = &H80000003 'HKEY_USERS
Const hkcc = &H80000005 'HKEY_CURRENT_CONFIG

dim allara(10,10)
dim alltab(10)
DIM ordcol(10,10)

'=== actual drive, actual directory, and "\"
thepath=WScript.ScriptFullName
p = instrRev(thepath,"\")
basedir  = left(thepath,p)
filnam = right(thepath,len(thepath)-p)

'=== windows dir
WinDir = objfso.GetSpecialFolder(0)

'=== restart the script in 32 bits if we are on a 64 bits system
'=== (databases drivers issues)
a64 = windir & "\syswow64\wscript.exe"

if objFSO.fileEXISTS(a64) and instr(lcase(wscript.fullname),"syswow64")=0 then
   '=== 64 bits system
   a = """" & a64 & """ """ & basedir & filnam & """"
   objshe.Run a,0, false
   wscript.quit
end if

'=== log everything in a file
logall = 1

'=== edit mode 0=off 1=on
'=== if edtmod = 1 every results will be in editable html boxes
edtmod = 0
totrec = 0
offset = 0
'=== no second search in the lower frame (fbot)
'=== this mean the search button is removed when table is generated
secseatag=0

dim tabnam,aratit,ara01,edtmod,offset,maxoff,myarray,component, strsearch, tab,sel,whe,objcon,tabnam2,ooper,wwild


priara = array(_
"<input type=""button"" onClick=""javascript:print()"" value=""Print""/><br><br>")
lefara = array(_
"<body background=""" & basedir & "images_interface\fond_gauche.jpg"">")
midara = array(_
"<body background=""" & basedir & "images_interface\fond_gris.jpg"">")
botara = array(_
"<body background=""" & basedir & "images_interface\fond_gris.jpg"">")

if logall=1 then
   '=== debug log
   file02 = basedir & "zzz_troubleshooting.txt"
   on error resume next
   Set Fil02 = objFSo.OpenTextFile(file02, 2, true)
   on error goto 0
end if





'============================================== main loop =============================================

'=== name of the user logged in window (network or not)
usenam=lcase(objnet.username)

'=== maximum row in the grid when more than the max
'=== we display only this number and a button "precedent" and "next" to swtich page
maxoff=15 '=== since 0 is included, 24 = 25 record

'=== menu items on left side (control side, frame: flef)

'= arabutnam: name of button, purely programmation name, used later to execute functions in main loop
'= arabutdes: description of button, text inside it actually
'= aradepnam: departement name, each departement (Section) is separated by a space
'= aradepcol: color of departement, blue = computer, brown = accounting, etc will follow a standard on internet (vague)
 
'=== button at the start for control frame (flef object)
'=== you can add as many buttons as you want, it's all dynamic (extendable)
if logall=1 then
   fil02.WriteLine date & " " & time & " START"
end if

x=0
ReDim Preserve arabutnam(x): ReDim Preserve arabutdes(x): ReDim Preserve aradepnam(x): ReDim Preserve aradepcol(x)
arabutnam(x)="facturation"
arabutdes(x)="Facturation"
aradepnam(x)="print"
aradepcol(x)="cccccc"

x=x+1
ReDim Preserve arabutnam(x): ReDim Preserve arabutdes(x): ReDim Preserve aradepnam(x): ReDim Preserve aradepcol(x)
arabutnam(x)="facturationnew"
arabutdes(x)="Facturation new"
aradepnam(x)="new"
aradepcol(x)="cccccc"

x=x+1
ReDim Preserve arabutnam(x): ReDim Preserve arabutdes(x): ReDim Preserve aradepnam(x): ReDim Preserve aradepcol(x)
arabutnam(x)="editxmlfile"
arabutdes(x)="Edit xml file"
aradepnam(x)="edition"
aradepcol(x)="cccccc"

x=x+1
ReDim Preserve arabutnam(x): ReDim Preserve arabutdes(x): ReDim Preserve aradepnam(x): ReDim Preserve aradepcol(x)
arabutnam(x)="displayxmlfile"
arabutdes(x)="Display xml file"
aradepnam(x)="display"
aradepcol(x)="cccccc"

x=x+1
ReDim Preserve arabutnam(x): ReDim Preserve arabutdes(x): ReDim Preserve aradepnam(x): ReDim Preserve aradepcol(x)
arabutnam(x)="clrframes"
arabutdes(x)="Clear Frames"
aradepnam(x)="OTHER"
aradepcol(x)="cccccc"

x=x+1
ReDim Preserve arabutnam(x): ReDim Preserve arabutdes(x): ReDim Preserve aradepnam(x): ReDim Preserve aradepcol(x)
arabutnam(x)="info"
arabutdes(x)="Information/Help"
aradepnam(x)="OTHER"
aradepcol(x)="cccccc"

x=x+1
ReDim Preserve arabutnam(x): ReDim Preserve arabutdes(x): ReDim Preserve aradepnam(x): ReDim Preserve aradepcol(x)
arabutnam(x)="quit01"
arabutdes(x)="Quitter"
aradepnam(x)="All"
aradepcol(x)="cccccc"

'=== old code for ref
'arabut=array("stristas", "striunig", "desarchive", "infocomp", "cretasks", "renamecomputer", "test", "clrframes", "quit01")
'arabutdes=array("Crée Structure i: Stas", "Crée Structure i: Unigec", "Désarchivage", "Info computer", "Create tasks", "Rename computer", "test divers",  "Clear Frames",    "Quitter")
'aradep=array("All", "All", "Informatique", "Informatique", "Informatique", "Informatique", "Other", "All")
'aradepcol=array("cccccc", "cccccc", "6699ff", "6699ff", "6699ff", "6699ff", "6699ff", "cccccc")

'=== i dont remember this one
lasdep=""
 
'=== web interface, internet explorer

'=== set the objects before calling functions, so they are global objects/variables, accessibles in all the program
set oIE = wscript.CreateObject("InternetExplorer.Application", "IE_")
dim flef, fmid, fbot

'=== title of internet explorer window
doctit = "titre de la page"

'=== title to display inside the left frame (control frame, flef object)
maitit = "Troubleshooting interface<br><br>STAS 45834"'=== title inside the left frame
maitit="<br><br><br><br>"

'=== create the main web interface with 3 frames, objects: flef, fmid, fbot
a = crewebmai(oie, doctit, maitit, arabutnam, arabutdes, aradepnam, aradepcol)

'=== defaut menu option for certain name logged
'=== example: a certain user will use always the same function
'=== so the interface will start, by executing this function at first, not an empty frame
'=== simply enter the name of the button that should be pressed for this user when interface start

if usenam="wildboy" or usenam="fournier.serge" then
   '=== defaut choice when program start
   'resbutlefstr = "stristas"
end if

'=== sub to call for each button
'=== here we define a sub to be called when a button in the web page is pressed
Do While (oIE.Busy)
   wscript.sleep 50
loop
do while oie.readystate<>4
   wscript.sleep 50
loop

'=== set up a return value on click of each button on the left frame
'=== the returned value is the name (programmable name) of each button (arabutnam)
'=== later any action will be taken according to this value
'=== i use this method because i dont want to call a sub when a button is pressed
'=== to remain in a loop for the main program, that is standard procedure in programming (to have a main loop)

for i=0 to ubound(arabutnam)
   flef.forms(0).elements(arabutnam(i)).onclick = getref("buttonlef")
next

'=== we also chek the key presse in each frame
'=== we do this cause we want "enter" key to be used instead of pressing "ok" button with the mouse
set flef.onkeypress = GetRef("Checklef")
set fmid.onkeypress = GetRef("Checkmid")
set fbot.onkeypress = GetRef("Checkbot")

'=== if bready = true, it mean they closed internet explorer, see the sub on internet explorer closing later in this code
'=== we have to chek this value often to stop the wscript.exe from interpreting this code, when internet explorer is closed
bReady=false
resbutlefstr = ""
resbutmidstr = ""
resbutbotstr = ""
reskeylef = 0
reskeymid = 0
reskeybot = 0

resblulefstr =""
resblumidstr =""
resblubotstr =""

resblulefid = ""
resblumidid = ""
resblubotid = ""

resblulefval =""
resblumidval =""
resblubotval =""


WScript.sleep(50) ' .1 seconds

'=== main loop, infinite
'=== unless someone press QUIT button
'=== or close internet explorer (bready = true)

do

if resbutlefstr="editxmlfile" then
a = clefra(array("fmid","fbot"))
resbutlefstr=""

x=0
redim preserve distmp(x) :redim preserve namtmp(x) :redim preserve deftmp(x) :redim preserve typtmp(x) :redim preserve errtmp(x)
distmp(x)="xml file name"      '===== description displayed in front of the field
namtmp(x)="text01"                  '===== name of variable for programming purpose
deftmp(x)=basedir & "facturation10.xml"          '===== default value
typtmp(x)="textbox"               '===== type of data: textbox password (futur: more to come)
errtmp(x)="enter a text to display" '===== text to display after the form "facultatif" blue text "error" red text are special keywords

buttmp=array("ok","cancel")       '===== at the end, there will be an "ok" button and a "cancel" button

a = dynforgen (distmp,namtmp,deftmp,typtmp,errtmp,buttmp,tit)

do
'=== flag to tell if the input is not valid
err01=0
'=== flag to say input is done, since there might be a defaut value, we must validate if user was finished
inpdon=0
'=== "ok" button or "enter" key are the same
'=== and nothing was pressed on left frame (control frame)

if resbutlefstr="" and (resbutmidstr="ok" or reskeymid=13) then
'=== User has clicked the OK button, retrieve the values
text=fmid.form01.text01.Value '=== namtmp is the variable name used earlier,before we call the dynamic form generation for input

if len(text) < 1 then
err01=1
'=== error message for the first form (if the keyword "error" is in this string, its displayed in RED)
if len(text) < 1 then
errtmp(0)="error - must be 1 char long at least"
else
errtmp(0)="ok"
end if

'=== if the value was not good, we generate the dynamic input for again, with an error message after the form in red
a = dynforgen(distmp,namtmp,deftmp,typtmp,errtmp,buttmp,tit)
'=== there was an invalid input so we reset the key or button pressed to nothing so the loop can continue
reskeymid=0
resbutmidstr=""
else
'=== the input was validated, we flag err01 to none, and flag inpdon to exit the loop
inpdon=1
err01=0
end if

end if
wscript.sleep 100

'=== while we wait for input value, user can press "escape" key, "cancel" button or close internet explorer
if resbutmidstr="cancel" or reskeymid=27 or bready=true or resbutlefstr<>"" then
'=== if user pressed escape or cancel, we clear the frames
if resbutmidstr="cancel" or reskeymid=27 then
a = clefra(array("fmid","fbot"))
resbutmidstr="cancel"
end if
exit do
end if
'=== if there was an input error and no one used left control frame to exit, we keep asking for input
loop while err01<>0 or inpdon=0

'=== if internet explorer was not closed (bready), a button was not pressed on left frame, and no excape or cancel in middle frame
if bready=false and resbutlefstr="" and reskeymid<>27 and resbutmidstr<>"cancel" then
'=== get values from input boxes
filename01 = fmid.form01.text01.Value

'=== open xml file
Set xmlDoc = CreateObject("Microsoft.XMLDOM")

xmlDoc.Async = "False"
xmlDoc.Load(filename01)
'Set objRoot = xmlDoc.documentElement

'=== root node level 0
'Set Node00 = objroot.SelectSingleNode("/*")

node = 1

'=== references
'https://msdn.microsoft.com/en-us/library/system.xml.xmlelement(v=vs.100).aspx

Set colNodes01 = xmlDoc.selectNodes("/*")

dummy = edit_xml_node(colNodes01, basedir & "\facturation" & numero01 & ".xml")

'xmlDoc.Save basedir & "\facturation" & numero01 & ".xml"

if bready=false and resbutlefstr="" and reskeymid<>27 and resbutmidstr<>"cancel" then
fbot.WriteLn("<br>FIN")

end if
end if

reskeymid=0
resbutmidstr=""
reskeylef=0

end if

if resbutlefstr="displayxmlfile" then
a = clefra(array("fmid","fbot"))
resbutlefstr=""

x=0
redim preserve distmp(x) :redim preserve namtmp(x) :redim preserve deftmp(x) :redim preserve typtmp(x) :redim preserve errtmp(x)
distmp(x)="xml file name"      '===== description displayed in front of the field
namtmp(x)="text01"                  '===== name of variable for programming purpose
deftmp(x)=basedir & "facturation9.xml"          '===== default value
typtmp(x)="textbox"               '===== type of data: textbox password (futur: more to come)
errtmp(x)="enter a text to display" '===== text to display after the form "facultatif" blue text "error" red text are special keywords

buttmp=array("ok","cancel")       '===== at the end, there will be an "ok" button and a "cancel" button

a = dynforgen (distmp,namtmp,deftmp,typtmp,errtmp,buttmp,tit)

do
'=== flag to tell if the input is not valid
err01=0
'=== flag to say input is done, since there might be a defaut value, we must validate if user was finished
inpdon=0
'=== "ok" button or "enter" key are the same
'=== and nothing was pressed on left frame (control frame)

if resbutlefstr="" and (resbutmidstr="ok" or reskeymid=13) then
'=== User has clicked the OK button, retrieve the values
text=fmid.form01.text01.Value '=== namtmp is the variable name used earlier,before we call the dynamic form generation for input

if len(text) < 1 then
err01=1
'=== error message for the first form (if the keyword "error" is in this string, its displayed in RED)
if len(text) < 1 then
errtmp(0)="error - must be 1 char long at least"
else
errtmp(0)="ok"
end if

'=== if the value was not good, we generate the dynamic input for again, with an error message after the form in red
a = dynforgen(distmp,namtmp,deftmp,typtmp,errtmp,buttmp,tit)
'=== there was an invalid input so we reset the key or button pressed to nothing so the loop can continue
reskeymid=0
resbutmidstr=""
else
'=== the input was validated, we flag err01 to none, and flag inpdon to exit the loop
inpdon=1
err01=0
end if

end if
wscript.sleep 100

'=== while we wait for input value, user can press "escape" key, "cancel" button or close internet explorer
if resbutmidstr="cancel" or reskeymid=27 or bready=true or resbutlefstr<>"" then
'=== if user pressed escape or cancel, we clear the frames
if resbutmidstr="cancel" or reskeymid=27 then
a = clefra(array("fmid","fbot"))
resbutmidstr="cancel"
end if
exit do
end if
'=== if there was an input error and no one used left control frame to exit, we keep asking for input
loop while err01<>0 or inpdon=0

'=== if internet explorer was not closed (bready), a button was not pressed on left frame, and no excape or cancel in middle frame
if bready=false and resbutlefstr="" and reskeymid<>27 and resbutmidstr<>"cancel" then
'=== get values from input boxes
filename01 = fmid.form01.text01.Value

'=== display your answers
'fmid.WriteLn("<br>Answer01: " & text01)
'fmid.WriteLn("<br>Answer02: " & text02)

'=== open xml file
Set xmlDoc = CreateObject("Microsoft.XMLDOM")

xmlDoc.Async = "False"
xmlDoc.Load(filename01)
Set objRoot = xmlDoc.documentElement

'=== root node level 0
'Set Node00 = objroot.SelectSingleNode("/*")

node = 1

'=== references
'https://msdn.microsoft.com/en-us/library/system.xml.xmlelement(v=vs.100).aspx

Set colNodes01 = xmlDoc.selectNodes("/*")



'=== make a big table that will contain other tables inside
h = "<!DOCTYPE html>"
h = h & "<html>"

h = h & "<head>"
h = h & "<style>"
h = h & "table#items01 tr:nth-child(even) {"
h = h & "background-color: #eee;"
h = h & "}"
h = h & "</style>"
h = h & "</head>"

h = h & "<body>"
h = h & "<table width=""100%"" BORDERCOLOR=""black"" class=MsoTableGrid border=1 CELLSPACING=0 cellpadding=2 style='border-collapse:collapse;border: 1px solid black'>"


'=== list all root nodes
For Each objNode01 in colNodes01
h = h & "<tr>" '=== line 1

h = h & "<td>" & objnode01.nodeName & "</td>"
'=== any node under root
for each objnode02 in objnode01.childnodes
h = h & "<tr>" '=== line 1
h = h & "<td></td><td>" & objnode02.nodename & "</td>"

For Each objChild02 In objnode02.childNodes
h = h & "<tr>"
if objchild02.text <>"" then
displaynamefra = objchild02.getattribute("displaynamefra")
h = h & "<td></td><td></td><td>" & objchild02.nodename  & "</td><td>" & displaynamefra & "</td><td>" & objchild02.text & "</td>"
'fbot.WriteLn("<td>" & displaynamefra & " " & objchild02.text)

end if
h = h & "</tr>" '=== line 1
next
h = h & "</tr>" '=== line 1
next
node = node+1
h = h & "</tr>" '=== line 1
next

xmlDoc.Save basedir & "\facturation" & numero01 & ".xml"

fbot.WriteLn(h)

fbot.WriteLn("<br>FIN")
end if

reskeymid=0
resbutmidstr=""
reskeylef=0


end if

if resbutlefstr="facturationnew" then

'=== this was a test with multiple button value (one for each line)
a = clefra(array("fmid","fbot"))
resbutlefstr=""

x=0
redim preserve distmp(x) :redim preserve namtmp(x) :redim preserve deftmp(x) :redim preserve typtmp(x) :redim preserve errtmp(x)
distmp(x)="Invoice number"      '===== description displayed in front of the field
namtmp(x)="text01"                  '===== name of variable for programming purpose
deftmp(x)="10"           '===== default value inside the form (the form will be 20 char long if no value here, but you can enter more)
typtmp(x)="textbox"               '===== type of data: textbox password (futur: more to come)
errtmp(x)="enter a text to display" '===== text to display after the form "facultatif" blue text "error" red text are special keywords

x=x+1
redim preserve distmp(x) :redim preserve namtmp(x) :redim preserve deftmp(x) :redim preserve typtmp(x) :redim preserve errtmp(x)
distmp(x)="Quantitée (heures)"      '===== description displayed in front of the field
namtmp(x)="text02"                  '===== name of variable for programming purpose
deftmp(x)=""           '===== default value inside the form (the form will be 20 char long if no value here, but you can enter more)
typtmp(x)="textbox"               '===== type of data: textbox password (futur: more to come)
errtmp(x)="enter a text to display" '===== text to display after the form "facultatif" blue text "error" red text are special keywords

x=x+1
redim preserve distmp(x) :redim preserve namtmp(x) :redim preserve deftmp(x) :redim preserve typtmp(x) :redim preserve errtmp(x)
distmp(x)="Tarif (rate)"      '===== description displayed in front of the field
namtmp(x)="text03"                  '===== name of variable for programming purpose
deftmp(x)=""           '===== default value inside the form (the form will be 20 char long if no value here, but you can enter more)
typtmp(x)="textbox"               '===== type of data: textbox password (futur: more to come)
errtmp(x)="enter a text to display" '===== text to display after the form "facultatif" blue text "error" red text are special keywords

x=x+1
redim preserve distmp(x) :redim preserve namtmp(x) :redim preserve deftmp(x) :redim preserve typtmp(x) :redim preserve errtmp(x)
distmp(x)="Référence employeur (bon de commande)"      '===== description displayed in front of the field
namtmp(x)="text04"                  '===== name of variable for programming purpose
deftmp(x)=""           '===== default value inside the form (the form will be 20 char long if no value here, but you can enter more)
typtmp(x)="textbox"               '===== type of data: textbox password (futur: more to come)
errtmp(x)="enter a text to display" '===== text to display after the form "facultatif" blue text "error" red text are special keywords

x=x+1
redim preserve distmp(x) :redim preserve namtmp(x) :redim preserve deftmp(x) :redim preserve typtmp(x) :redim preserve errtmp(x)
distmp(x)="Time line"      '===== description displayed in front of the field
namtmp(x)="text05"                  '===== name of variable for programming purpose
deftmp(x)="semaine du 2015"           '===== default value inside the form (the form will be 20 char long if no value here, but you can enter more)
typtmp(x)="textbox"               '===== type of data: textbox password (futur: more to come)
errtmp(x)="enter a text to display" '===== text to display after the form "facultatif" blue text "error" red text are special keywords

buttmp=array("ok","cancel")       '===== at the end, there will be an "ok" button and a "cancel" button

a = dynforgen (distmp,namtmp,deftmp,typtmp,errtmp,buttmp,tit)

do
'=== flag to tell if the input is not valid
err01=0
'=== flag to say input is done, since there might be a defaut value, we must validate if user was finished
inpdon=0
'=== "ok" button or "enter" key are the same
'=== and nothing was pressed on left frame (control frame)

if resbutlefstr="" and (resbutmidstr="ok" or reskeymid=13) then
'=== User has clicked the OK button, retrieve the values
text=fmid.form01.text01.Value '=== namtmp is the variable name used earlier,before we call the dynamic form generation for input

if len(text) < 1 then
err01=1
'=== error message for the first form (if the keyword "error" is in this string, its displayed in RED)
if len(text) < 1 then
errtmp(0)="error - must be 1 char long at least"
else
errtmp(0)="ok"
end if

'=== if the value was not good, we generate the dynamic input for again, with an error message after the form in red
a = dynforgen(distmp,namtmp,deftmp,typtmp,errtmp,buttmp,tit)
'=== there was an invalid input so we reset the key or button pressed to nothing so the loop can continue
reskeymid=0
resbutmidstr=""
else
'=== the input was validated, we flag err01 to none, and flag inpdon to exit the loop
inpdon=1
err01=0
end if

end if
wscript.sleep 100

'=== while we wait for input value, user can press "escape" key, "cancel" button or close internet explorer
if resbutmidstr="cancel" or reskeymid=27 or bready=true or resbutlefstr<>"" then
'=== if user pressed escape or cancel, we clear the frames
if resbutmidstr="cancel" or reskeymid=27 then
a = clefra(array("fmid","fbot"))
resbutmidstr="cancel"
end if
exit do
end if
'=== if there was an input error and no one used left control frame to exit, we keep asking for input
loop while err01<>0 or inpdon=0

'=== if internet explorer was not closed (bready), a button was not pressed on left frame, and no excape or cancel in middle frame
if bready=false and resbutlefstr="" and reskeymid<>27 and resbutmidstr<>"cancel" then
'=== get values from input boxes
numero01 = fmid.form01.text01.Value
quantity01 = fmid.form01.text02.Value
rate01 = fmid.form01.text03.Value
billto_reference01 = fmid.form01.text04.Value
timeline01 = fmid.form01.text05.Value

'=== display your answers
'fmid.WriteLn("<br>Answer01: " & text01)
'fmid.WriteLn("<br>Answer02: " & text02)
'reference
'http://www.w3schools.com/xml/dom_element.asp


'fbot.WriteLn("<br>TESTING XML STUFF")
'fbot.WriteLn("<br>directory where xml file is saved: " & basedir)

'=== goal: have an xml list of items to generate an invoice


'=== do not create

'=== create xml
Set xmlDoc = CreateObject("Microsoft.XMLDOM")
Set objRoot = xmlDoc.createElement("facturation")
xmlDoc.appendChild objRoot

'Set objRecord = xmlDoc.createElement("source")
'objRoot.appendChild objRecord

'Set objName = xmlDoc.createElement("nom")
'objName.Text = "Serge Fournier"
'objRecord.appendChild objName

'Set objDate = xmlDoc.createElement("datecreation")
'objDate.Text = Date
'objRecord.appendChild objDate

Set objIntro = xmlDoc.createProcessingInstruction("xml","version='1.0'")
xmlDoc.insertBefore objIntro,xmlDoc.childNodes(0)

xmlDoc.Save basedir & "\facturation" & numero01 & ".xml"

'=== add a record
Set xmlDoc = CreateObject("Microsoft.XMLDOM")

xmlDoc.Async = "False"
xmlDoc.Load(basedir & "\facturation" & numero01 & ".xml")

Set objRoot = xmlDoc.documentElement

Set objRecord = xmlDoc.createElement("bill")
objRoot.appendChild objRecord

Set objFieldValue = xmlDoc.createElement("id")
objfieldvalue.SetAttribute "displaynamefra", "Numéro"
objFieldValue.Text = numero01
objRecord.appendChild objFieldValue

Set objFieldValue = xmlDoc.createElement("date")
objfieldvalue.SetAttribute "displaynamefra", "Date émise"
objFieldValue.Text = date
objRecord.appendChild objFieldValue

Set objFieldValue = xmlDoc.createElement("datedue")
objfieldvalue.SetAttribute "displaynamefra", "Date due"
objFieldValue.Text = date
objRecord.appendChild objFieldValue

Set objFieldValue = xmlDoc.createElement("billto_reference")
objfieldvalue.SetAttribute "displaynamefra", "Référence de l'employeur"
objFieldValue.Text = billto_reference01
objRecord.appendChild objFieldValue

Set objRecord = xmlDoc.createElement("billfrom")
objRoot.appendChild objRecord
objRecord.SetAttribute "displaynamefra", "Contracteur"

Set objFieldValue = xmlDoc.createElement("compagny")
objfieldvalue.SetAttribute "displaynamefra", "Compagnie"
objFieldValue.Text = ""
objRecord.appendChild objFieldValue

Set objFieldValue = xmlDoc.createElement("name")
objfieldvalue.SetAttribute "displaynamefra", "Nom"
objFieldValue.Text = "Serge Fournier"
objRecord.appendChild objFieldValue

Set objFieldValue = xmlDoc.createElement("addressnumber")
objfieldvalue.SetAttribute "displaynamefra", "Adresse"
objFieldValue.Text = ""
objRecord.appendChild objFieldValue

Set objFieldValue = xmlDoc.createElement("addressstreet")
objfieldvalue.SetAttribute "displaynamefra", "Rue"
objFieldValue.Text = ""
objRecord.appendChild objFieldValue

Set objFieldValue = xmlDoc.createElement("addresscity")
objfieldvalue.SetAttribute "displaynamefra", "Ville"
objFieldValue.Text = ""
objRecord.appendChild objFieldValue

Set objFieldValue = xmlDoc.createElement("addresszip")
objfieldvalue.SetAttribute "displaynamefra", "Code postal"
objFieldValue.Text = ""
objRecord.appendChild objFieldValue

Set objFieldValue = xmlDoc.createElement("addressstate")
objfieldvalue.SetAttribute "displaynamefra", "Province"
objFieldValue.Text = ""
objRecord.appendChild objFieldValue

Set objFieldValue = xmlDoc.createElement("addresscountry")
objfieldvalue.SetAttribute "displaynamefra", "Pays"
objFieldValue.Text = "Canada"
objRecord.appendChild objFieldValue

Set objFieldValue = xmlDoc.createElement("phonehome")
objfieldvalue.SetAttribute "displaynamefra", "Téléphone (residence)"
objFieldValue.Text = ""
objRecord.appendChild objFieldValue

Set objFieldValue = xmlDoc.createElement("email")
objfieldvalue.SetAttribute "displaynamefra", "Courriel"
objFieldValue.Text = ""
objRecord.appendChild objFieldValue

Set objFieldValue = xmlDoc.createElement("phonecell")
objfieldvalue.SetAttribute "displaynamefra", "Téléphone (cellulaire)"
objFieldValue.Text = ""
objRecord.appendChild objFieldValue

Set objRecord = xmlDoc.createElement("billto")
objRoot.appendChild objRecord

'31, Racine O., First floor, Saguenay ,QC ,Canada ,G7J 1E4

Set objFieldValue = xmlDoc.createElement("compagny")
objfieldvalue.SetAttribute "displaynamefra", "Compagnie"
objFieldValue.Text = ""
objRecord.appendChild objFieldValue

Set objFieldValue = xmlDoc.createElement("name")
objfieldvalue.SetAttribute "displaynamefra", "Nom"
objFieldValue.Text = ""
objRecord.appendChild objFieldValue

Set objFieldValue = xmlDoc.createElement("addressnumber")
objfieldvalue.SetAttribute "displaynamefra", "Adresse"
objFieldValue.Text = ""
objRecord.appendChild objFieldValue

Set objFieldValue = xmlDoc.createElement("addressstreet")
objfieldvalue.SetAttribute "displaynamefra", "Rue"
objFieldValue.Text = ""
objRecord.appendChild objFieldValue

Set objFieldValue = xmlDoc.createElement("addresscity")
objfieldvalue.SetAttribute "displaynamefra", "Ville"
objFieldValue.Text = ""
objRecord.appendChild objFieldValue

Set objFieldValue = xmlDoc.createElement("addresszip")
objfieldvalue.SetAttribute "displaynamefra", "Code postal"
objFieldValue.Text = ""
objRecord.appendChild objFieldValue

Set objFieldValue = xmlDoc.createElement("addressstate")
objfieldvalue.SetAttribute "displaynamefra", "Province"
objFieldValue.Text = ""
objRecord.appendChild objFieldValue

Set objFieldValue = xmlDoc.createElement("addresscountry")
objfieldvalue.SetAttribute "displaynamefra", "Pays"
objFieldValue.Text = "Canada"
objRecord.appendChild objFieldValue

Set objRecord = xmlDoc.createElement("billitems")
objRoot.appendChild objRecord

Set objFieldValue = xmlDoc.createElement("id")
objfieldvalue.SetAttribute "displaynamefra", "Item #"
objFieldValue.Text = "1"
objRecord.appendChild objFieldValue

Set objFieldValue = xmlDoc.createElement("id_bill")
objfieldvalue.SetAttribute "displaynamefra", "Référence facture"
objFieldValue.Text = numero01
objRecord.appendChild objFieldValue

Set objFieldValue = xmlDoc.createElement("description")
objfieldvalue.SetAttribute "displaynamefra", "Description"
objFieldValue.Text = "Administration réseau et technique informatique"
objRecord.appendChild objFieldValue

Set objFieldValue = xmlDoc.createElement("timeline")
objfieldvalue.SetAttribute "displaynamefra", "Période"
objFieldValue.Text = timeline01
objRecord.appendChild objFieldValue

Set objFieldValue = xmlDoc.createElement("unity")
objfieldvalue.SetAttribute "displaynamefra", "Unitée"
objFieldValue.Text = "Heures"
objRecord.appendChild objFieldValue

Set objFieldValue = xmlDoc.createElement("quantity")
objfieldvalue.SetAttribute "displaynamefra", "Quantité"
objFieldValue.Text = quantity01
objRecord.appendChild objFieldValue

Set objFieldValue = xmlDoc.createElement("rate")
objfieldvalue.SetAttribute "displaynamefra", "Tarif"
objFieldValue.Text = rate01
objRecord.appendChild objFieldValue


xmlDoc.Save basedir & "\facturation" & numero01 & ".xml"

fmid.WriteLn("<br>New invoice created")

reskeymid=0
resbutmidstr=""
reskeylef=0


end if
end if
'''''''''''''''''''''''''''''''''''''
' facturation invoice (display)
'''''''''''''''''''''''''''''''''''''
if resbutlefstr="facturation" then

'=== this was a test with multiple button value (one for each line)
a = clefra(array("fmid","fbot"))

x=0
redim preserve distmp(x) :redim preserve namtmp(x) :redim preserve deftmp(x) :redim preserve typtmp(x) :redim preserve errtmp(x)
distmp(x)="Invoice number"      '===== description displayed in front of the field
namtmp(x)="text01"                  '===== name of variable for programming purpose
deftmp(x)="10"           '===== default value inside the form (the form will be 20 char long if no value here, but you can enter more)
typtmp(x)="textbox"               '===== type of data: textbox password (futur: more to come)
errtmp(x)="enter a text to display" '===== text to display after the form "facultatif" blue text "error" red text are special keywords

buttmp=array("ok","cancel")       '===== at the end, there will be an "ok" button and a "cancel" button

a = dynforgen (distmp,namtmp,deftmp,typtmp,errtmp,buttmp,tit)

do
'=== flag to tell if the input is not valid
err01=0
'=== flag to say input is done, since there might be a defaut value, we must validate if user was finished
inpdon=0
'=== "ok" button or "enter" key are the same
'=== and nothing was pressed on left frame (control frame)

if resbutlefstr="" and (resbutmidstr="ok" or reskeymid=13) then
'=== User has clicked the OK button, retrieve the values
text=fmid.form01.text01.Value '=== namtmp is the variable name used earlier,before we call the dynamic form generation for input

if len(text) < 1 then
err01=1
'=== error message for the first form (if the keyword "error" is in this string, its displayed in RED)
if len(text) < 1 then
errtmp(0)="error - must be 1 char long at least"
else
errtmp(0)="ok"
end if

'=== if the value was not good, we generate the dynamic input for again, with an error message after the form in red
a = dynforgen(distmp,namtmp,deftmp,typtmp,errtmp,buttmp,tit)
'=== there was an invalid input so we reset the key or button pressed to nothing so the loop can continue
reskeymid=0
resbutmidstr=""
else
'=== the input was validated, we flag err01 to none, and flag inpdon to exit the loop
inpdon=1
err01=0
end if

end if
wscript.sleep 100

'=== while we wait for input value, user can press "escape" key, "cancel" button or close internet explorer
if resbutmidstr="cancel" or reskeymid=27 or bready=true or resbutlefstr<>"" then
'=== if user pressed escape or cancel, we clear the frames
if resbutmidstr="cancel" or reskeymid=27 then
a = clefra(array("fmid","fbot"))
resbutmidstr="cancel"
end if
exit do
end if
'=== if there was an input error and no one used left control frame to exit, we keep asking for input
loop while err01<>0 or inpdon=0

'=== if internet explorer was not closed (bready), a button was not pressed on left frame, and no excape or cancel in middle frame
if bready=false and resbutlefstr="" and reskeymid<>27 and resbutmidstr<>"cancel" then
'=== get values from input boxes
numero01 = fmid.form01.text01.Value
'quantity01 = fmid.form01.text02.Value
'rate01 = fmid.form01.text03.Value
'billto_reference01 = fmid.form01.text04.Value
'timeline01 = fmid.form01.text05.Value

'=== display your answers
fmid.WriteLn("<br>Answer01: " & text01)
fmid.WriteLn("<br>Answer02: " & text02)
'reference
'http://www.w3schools.com/xml/dom_element.asp


'fbot.WriteLn("<br>TESTING XML STUFF")
'fbot.WriteLn("<br>directory where xml file is saved: " & basedir)

'=== goal: have an xml list of items to generate an invoice

'=== affiche la facture dans le frame du bas

Set xmlDoc = CreateObject("Microsoft.XMLDOM")

xmlDoc.Async = "False"
xmlDoc.Load(basedir & "\facturation" & numero01 & ".xml")

'=== id facture
id_bill = numero01

'=== ROOT:
'=== facturation
'=== RECORDS:
'=== bill, billfrom, billto, billitems
'Set colNodes=xmlDoc.selectNodes("/facturation/ComputerAudit [ComputerName = 'atl-ws-100']")

'=== make a big table that will contain other tables inside
h = "<!DOCTYPE html>"
h = h & "<html>"

h = h & "<head>"
h = h & "<style>"
h = h & "table#items01 tr:nth-child(even) {"
h = h & "background-color: #eee;"
h = h & "}"
h = h & "</style>"
h = h & "</head>"

h = h & "<body>"
h = h & "<table width=""100%"" BORDERCOLOR=""black"" class=MsoTableGrid border=1 CELLSPACING=0 cellpadding=2 style='border-collapse:collapse;border: 3px solid black'>"
h = h & "<tr>" '=== line 1

''''''''''''''''''''''''''''''''
' billfrom
''''''''''''''''''''''''''''''''
h = h & "<td>" '=== column

'h = h & "<h1>Facture de:</h1>"
h = h & "<table width=""100%"" BORDERCOLOR=""black"" class=MsoTableGrid border=1 CELLSPACING=0 cellpadding=2 style='border-collapse:collapse;border:none'>"

Set colNodes=xmlDoc.selectNodes("/facturation/billfrom")

node = 1
For Each objNode in colNodes

'=== there is supposed to be only one node, one bill or invoice
For Each objChild In objnode.childNodes
if objchild.text <>"" then
h = h & "<tr>"

displaynamefra = objchild.getattribute("displaynamefra")
h = h & "<td>" & displaynamefra & "</td><td>" & objchild.text & "</td>"

h = h & "</tr>"
end if

next
node = node + 1
next

h = h & "</table>"
h = h & "</td>"

''''''''''''''''''''''''''''''''
' invoice
''''''''''''''''''''''''''''''''
h = h & "<td>"
h = h & "<table width=""100%"" BORDERCOLOR=""black"" class=MsoTableGrid border=1 CELLSPACING=0 cellpadding=2 style='border-collapse:collapse;border:none'>"

h = h & "<tr><td><center><h1>FACTURE</h1></center></td></tr>"

h = h & "</table>"
h = h & "</td>"

h = h & "</tr>" '=== line 1 end

h = h & "<tr>" '=== line 2

''''''''''''''''''''''''''''''''
' billto
''''''''''''''''''''''''''''''''
Set colNodes=xmlDoc.selectNodes("/facturation/billto")
h = h & "<td>"

h = h & "<h1>Facturé à:</h1>"
h = h & "<table width=""100%"" BORDERCOLOR=""black"" class=MsoTableGrid border=1 CELLSPACING=0 cellpadding=2 style='border-collapse:collapse;border:none'>"

Set colNodes=xmlDoc.selectNodes("/facturation/billto")

node = 1
For Each objNode in colNodes

'=== there is supposed to be only one node, one bill or invoice
For Each objChild In objnode.childNodes

h = h & "<tr>"
'fbot.WriteLn("<br>child node")
if objchild.text <>"" then
displaynamefra = objchild.getattribute("displaynamefra")
h = h & "<td>" & displaynamefra & "</td><td>" & objchild.text & "</td>"
end if
h = h & "</tr>"

next
'if objnode.text <>"" then
' displaynamefra = objnode.getattribute("displaynamefra")
' fbot.WriteLn("<br>node: " & node & " --- " & displaynamefra & " --- " & objnode.text)
'end if
node = node + 1

next

h = h & "</table>"

h = h & "</td>"

''''''''''''''''''''''''''''''''
' bill id and stuff
''''''''''''''''''''''''''''''''
h = h & "<td>"
h = h & "<table width=""100%"" BORDERCOLOR=""black"" class=MsoTableGrid border=1 CELLSPACING=0 cellpadding=2 style='border-collapse:collapse;border:none'>"

Set colNodes=xmlDoc.selectNodes("/facturation/bill [id = '" & id_bill & "']")

node = 1
For Each objNode in colNodes

'=== there is supposed to be only one node, one bill or invoice
For Each objChild In objnode.childNodes

h = h & "<tr>"
'fbot.WriteLn("<br>child node")
if objchild.text <>"" then
displaynamefra = objchild.getattribute("displaynamefra")
h = h & "<td>" & displaynamefra & "</td><td>" & objchild.text & "</td>"
end if
h = h & "</tr>"

next
'if objnode.text <>"" then
' displaynamefra = objnode.getattribute("displaynamefra")
' fbot.WriteLn("<br>node: " & node & " --- " & displaynamefra & " --- " & objnode.text)
'end if
node = node + 1

next

h = h & "</table>"

h = h & "</td>"
h = h & "</tr>" '=== line 2 end

h = h & "</tr>" '=== end 4 first squares

'''''''''''''''''''''''''''
' items
'''''''''''''''''''''''''''

h = h & "<td colspan=""2"">"

h = h & "<table id=""items01"" width=""100%"" BORDERCOLOR=""black"" class=MsoTableGrid border=1 CELLSPACING=0 cellpadding=2 style='border-collapse:collapse;border:none'>"

Set colNodes=xmlDoc.selectNodes("/facturation/billitems [id_bill = '" & id_bill & "']")
'fbot.WriteLn("<br>Numéro de la facture: " & id_bill)

Set colNodes=xmlDoc.selectNodes("/facturation/billitems")

'=== column titles
node = 1
h = h & "<tr>"
For Each objNode in colNodes

'=== there is supposed to be only one node, one bill or invoice
For Each objChild In objnode.childNodes
'fbot.WriteLn("<br>child node")

displaynamefra = objchild.getattribute("displaynamefra")
h = h & "<td>" & displaynamefra & "</td>"

next

h = h & "<td>Montant</td>"
'if objnode.text <>"" then
' displaynamefra = objnode.getattribute("displaynamefra")
' fbot.WriteLn("<br>node: " & node & " --- " & displaynamefra & " --- " & objnode.text)
'end if
node = node + 1

next
h = h & "</tr>"

'=== data in columns, line by line
total01 = 0
node = 1
For Each objNode in colNodes
h = h & "<tr>"
'=== there is supposed to be only one node, one bill or invoice
quantity01 = ""
rate01 = ""
nodecol = 0
For Each objChild In objnode.childNodes
'fbot.WriteLn("<br>child node")
displaynamefra = objchild.getattribute("displaynamefra")
if objchild.nodename = "rate" then prefix01 = "$ " else prefix01 = ""
h = h & "<td>" & prefix01 & objchild.text & "</td>"
if objchild.nodename = "quantity" then quantity01 = objchild.text
if objchild.nodename = "rate" then rate01 = objchild.text
nodecol = nodecol + 1
next
subtot01 = quantity01 * rate01
h = h & "<td>$ " & subtot01 & "</td>"
'if objnode.text <>"" then
' displaynamefra = objnode.getattribute("displaynamefra")
' fbot.WriteLn("<br>node: " & node & " --- " & displaynamefra & " --- " & objnode.text)
'end if
node = node + 1
h = h & "</tr>"

total01 = total01 + subtot01
next

'=== final line - total01
h = h & "<tr>"

'=== merge this to get total on right side, last 2 columns
h = h & "<td colspan=""" & nodecol-1 & """></td>"

h = h & "<td>Total (can)</td>"
h = h & "<td>$ " & total01 & "</td>"

h = h & "</tr>"

h = h & "</table>"

h = h & "</td>"
h = h & "</tr>" '=== line 2
h = h & "</body>"
h = h & "</html>"

'h = h & "<br>Total bills found: " & node-1 & " with " & id_bill & " as ID"
fbot.WriteLn(h)

'=== XML modification
Set xmlDoc = CreateObject("Microsoft.XMLDOM")

xmlDoc.Async = "False"
xmlDoc.Load(basedir & "\facturation" & numero01 & ".xml")

Set colNodes=xmlDoc.selectNodes("/facturation/source [nom = 'Serge Fournier']/datecreation")

For Each objNode in colNodes
  objNode.Text = "caca"
  fbot.WriteLn(text & "<br>node")
Next

xmlDoc.Save basedir & "\facturation" & numero01 & ".xml"



'=== remove an element
Set xmlDoc = CreateObject("Microsoft.XMLDOM")

xmlDoc.Async = "False"
xmlDoc.Load(basedir & "\facturation" & numero01 & ".xml")

Set colNodes=xmlDoc.selectNodes   ("/ITChecklist/ComputerAudit [ComputerName = 'atl-ws-100']")

For Each objNode in colNodes
 xmlDoc.documentElement.removeChild(objNode)
Next

xmlDoc.Save basedir & "\facturation" & numero01 & ".xml"

fmid.WriteLn("<br><br>Done")

'=== open xml and make a html table ready to print

end if

reskeymid=0
resbutmidstr=""
reskeylef=0
resbutlefstr=""

end if


   '=== if the button named this is pressed we do this
   '=== resbutlefstr: result from pressing a button in the left frame (control frame, flef object)
   '=== its a string that contain the programmable name of the button that was pressed in the left frame (arabutnam)
 
   if resbutlefstr="clrframes" then

      a = clefra(array("fmid","fbot"))

      'fbot.WriteLn("tried to clear middle frame")
 
   end if
 
   if resbutlefstr="info" then
      a = clefra(array("fmid","fbot"))
   
      '=== print button
      aa = lcase(fbot.readystate)
      do until aa="complete" or aa="terminé" or aa="interactive"
         'if logall = 1 then fil02.writeline "*********************************** readystate of " & ffranam & ": " & aa
         wscript.sleep 100
         aa = lcase(fbot.readystate)
      loop
     
      for each a in priara
         fbot.WriteLn(a)
      next
      for each a in botara
         fbot.WriteLn(a)
      next
   
 
      fbot.WriteLn("<H2>Crucible Cleaner Troubleshooting Database with Dynamic Web Interface</H2><br>")
 
      texara=array(_
      "",_
      "1. REQUIREMENTS:",_
      "1.1 Microsoft windows xp, vista (32 or 64), seven (32 or 64) (without UAC, users access control, off)",_
      "1.2 Internet explorer",_
      "1.3 .NET framework 1.1 (included with windows)",_
      "",_
      "2. CARACTERISTICS:",_
      "",_
      "2.1 This dynamic web interface was programmed to access a microsoft access database information to troubleshoot a Crucible Cleaner",_
      "",_
      "3. REFERENCES:",_
      "",_
      "Contact: Serge Fournier, Prog./Analyst")
   
      for each a in texara
         aa = lcase(fbot.readystate)
         do until aa="complete" or aa="terminé" or aa="interactive"
            if logall = 1 then fil02.writeline "*********************************** readystate of " & ffranam & ": " & aa
            wscript.sleep 100
            'aa = lcase(fbot.readystate)
         loop
         fbot.WriteLn(a & "<br>")
      next
      aa = lcase(fbot.readystate)
      do until aa="complete" or aa="terminé" or aa="interactive"
         if logall = 1 then fil02.writeline "*********************************** readystate of " & ffranam & ": " & aa
         wscript.sleep 100
         'aa = lcase(fbot.readystate)
      loop
   
      fbot.location.reload(true)
   
      reskeymid=0
      resbutmidstr=""
   
   end if
   '==========================================
 
   if resbutlefstr="newdb" then
      '=== create a new database mdb type (Access 2000)
      tit="new database" '=== title to display in fmid frame (input frame)
   
      '=== clear 2 frames (input: fmid, and result: fbot)
      '=== also clear the result button name for all frames and the key pressed on all frames
      a = clefra(array("fmid","fbot"))
   
      '=== dynamic generation of input form, and control buttons in fmid (middle or up frame, called "input" frame for more clarity, fmid object)
   
      '=== inputs to do before processing
      '=== you can add more input forms, at the end, there will be an "ok" button and a "cancel" button

      x=0
      redim preserve distmp(x) :redim preserve namtmp(x) :redim preserve deftmp(x) :redim preserve typtmp(x) :redim preserve errtmp(x)
      distmp(x)="Database name"      '===== description displayed in front of the field
      namtmp(x)="dbnam"                 '===== name of variable for programming purpose
      deftmp(x)="testmdbaccess2000"     '===== default value inside the form (the form will be 20 char long if no value here, but you can enter more)
      typtmp(x)="textbox"               '===== type of data: textbox password (futur: more to come)
      errtmp(x)=".MDB enter name of DB file" '===== text to display after the form "facultatif" blue text "error" red text are special keywords

      x=x+1
      redim preserve distmp(x) :redim preserve namtmp(x) :redim preserve deftmp(x) :redim preserve typtmp(x) :redim preserve errtmp(x)
      distmp(x)="Table name"      '===== description displayed in front of the field
      namtmp(x)="tabnam"                 '===== name of variable for programming purpose
      deftmp(x)="table01"     '===== default value inside the form (the form will be 20 char long if no value here, but you can enter more)
      typtmp(x)="textbox"               '===== type of data: textbox password (futur: more to come)
      errtmp(x)="enter name of first table" '===== text to display after the form "facultatif" blue text "error" red text are special keywords
   
      buttmp=array("ok","cancel")       '===== at the end, there will be an "ok" button and a "cancel" button
   
      a = dynforgen (distmp,namtmp,deftmp,typtmp,errtmp,buttmp,tit)
   
      do
         '=== flag to say input is done, since there might be a defaut value, we must validate if user was finished
         inpdon=0
         err01=0
       
         '=== "ok" button or "enter" key are the same
         '=== and nothing was pressed on left frame (control frame)
       
         if resbutlefstr="" and (resbutmidstr="ok" or reskeymid=13) then
   
            '=== User has clicked the OK button, retrieve the values
            dbnam = fmid.form01.dbnam.Value '=== namtmp is the variable name used earlier,before we call the dynamic form generation for input
            dbnam=lcase(dbnam)
         
            tabnam = fmid.form01.tabnam.Value '=== namtmp is the variable name used earlier,before we call the dynamic form generation for input
            tabnam=lcase(tabnam)

            if len(dbnam) < 1 or len(tabnam)<1 then
               err01=1
               '=== error message for the first form (if the keyword "error" is in this string, its displayed in RED)
               if len(dbnam) < 1 then
                  errtmp(0)="error - name must be 1 char long at least"
               else
                  errtmp(0)="ok"
               end if
               if len(tabnam) < 1 then
                  errtmp(1)="error - name must be 1 char long at least"
               else
                  errtmp(1)="ok"
               end if

               '=== if the value was not good, we generate the dynamic input for again, with an error message after the form in red
               a = dynforgen(distmp,namtmp,deftmp,typtmp,errtmp,buttmp,tit)
               reskeymid=0
               resbutmidstr=""
            else
               '=== the input was validated, we flag err01 to none, and flag inpdon to exit the loop
               inpdon=1
               err01=0
            end if
         
         end if
         wscript.sleep 100
   
         '=== while we wait for input value, user can press "escape" key, "cancel" button or close internet explorer
         if resbutmidstr="cancel" or reskeymid=27 or bready=true or resbutlefstr<>"" then
            '=== if user pressed escape or cancel, we clear the frames
            if resbutmidstr="cancel" or reskeymid=27 then
               a = clefra(array("fmid","fbot"))
               resbutmidstr="cancel"
            end if
            exit do
         end if
       
      '=== if there was an input error and no one used left control frame to exit, we keep asking for input
      loop while err01<>0 or inpdon=0
   '===
      if bready=false and resbutlefstr="" and reskeymid<>27 and resbutmidstr<>"cancel" then
         '=== all value were validated, we continue
         dbnam = dbnam & ".mdb"
   
         '=== chek if the file already exist
         Set objFolder2 = objFSO.GetFolder(basedir)'=== dir
         Set objFiles2 = objFolder2.files '=== fichiers

         found=0
         For Each objFile3 in objFiles2
            nomfile=objfile3.name
            nomfile=lcase(nomfile)
            if nomfile=dbnam then
               found=1
            end if
         next
         if found=1 then
            a = clefra(array("fmid"))
            fbot.WriteLn("The file: <br>" & dbnam & "<br>Already exist<br><br>Please use EDIT DATABASE to manage it<br><br>")
            fbot.WriteLn("FIN<br><br>")
       
            fbot.WriteLn("LIST of table in the existing database:<br><br>")
            Set objcat = CreateObject("ADOX.Catalog")
            Set objcon = CreateObject("ADODB.Connection")
            constr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & dbnam
            objcon.open constr
            objcat.activeconnection=(objcon)
            for each tab in objcat.Tables
               If tab.Type = "TABLE" Then
                  fbot.WriteLn("<br>TABLES:<br><br>")
                  fbot.WriteLn(tab.name & "<br>")
                  fbot.WriteLn("<br>COLUMNS:<br><br>")
                  for each col in tab.columns
                     c = lcase(col.name)
                     fbot.WriteLn(c & "<br>Type: " & col.type & "&nbsp&nbsp&nbspAutoincrement: " & col.Properties("AutoIncrement") & "<br>")
                  next
               end if
            next
            objcon.close
            set objcat=nothing
            set objcon=nothing
         else
            a = clefra(array("fmid"))
            '=== formats: jet10 = 1 Jet11 = 2 Jet20 = 3 Jet3x = 4 Jet4x = 5 (Access 2000)
            Dim Catalog
            fbot.WriteLn("Creation ADOX catalog (adox.dll, access required)<br><br>")
       
            Set objcat = CreateObject("ADOX.Catalog")
            format = 5
            fbot.WriteLn("database creation: " & dbnam & "<br><br>")
       
            constr="Provider=Microsoft.Jet.OLEDB.4.0;" & "Jet OLEDB:Engine Type=" & Format & ";Data Source=" & dbnam
            objcat.Create constr

            '=== add a table in the database
            fbot.WriteLn("table creation: " & tabnam &"<br>")
            Set objtab = CreateObject("ADOX.table")
            objtab.name = tabnam
            objcat.Tables.Append objtab
            objcat.Tables.refresh
       
            '=== add a columns in the only existing table
            for each tab in objcat.Tables
               If tab.Type = "TABLE" Then
         
                  fbot.WriteLn("table existing: " & tab.name & "<br>")
                  '=== add column in database
                  Set objcol = Nothing
                  colnam="codintsef"
                  a=crecol(tab,colnam)

                  fbot.WriteLn("primary key creation: " & colnam & "<br>")
                  Set objkey = CreateObject("ADOX.key")
                  objkey.name="Primary"
                  objkey.columns.append colnam
                  tab.keys.append objkey
             
                  'Set aIndex = New ADOX.Index
                  'aIndex.Name = "ByField2"
                  'aIndex.Clustered = False
                  'aIndex.Columns.Append "Field2"
                  'aIndex.Columns.Append "Field1"
                  'aTable.Indexes.Append aIndex ' save the index

                  for each col in tab.columns
                     c = lcase(col.name)
                     fbot.WriteLn("column existing: " & c & "&nbsp&nbsp&nbspautoincrement status: " & objcol.Properties("AutoIncrement") & "<br>")
                  next
             
               end if
            next
       
            set objcat=nothing
       
            fbot.WriteLn("<br>You database have been created with 1 table and a defaut column named " & colnam & "<br>")
            fbot.WriteLn("<br>END<br>")
         end if
      else
      'msgbox(resbutlefstr & "   " & resbutmidstr & "   " & resmidkey & "   " & bready)
   '===
      end if
      reskeymid=0
      resbutmidstr=""
      dbnam=""
   end if
 
   '===========================
   '===========================
   '===========================
   '===========================
 
   if resbutlefstr="edtdb" then
      resbutlefstr = ""

      a = clefra(array("fmid","fbot"))
   
      '=== value
      '=== chek if the file already exist
      Set objFol01=objFSO.GetFolder(basedir)'=== dir
      Set objfol02=objFol01.files '=== files
   
      x=0
      redim ara01(0)
      dimnum=1
      For Each objFil in objFol02
         filnam=objfil.name
         filnam=lcase(filnam)
         if right(filnam,4)=".mdb" then
            redim preserve ara01(x)
            ara01(x)=filnam
            x=x+1
         end if
      next
   
      '=== title of the columns
      aratit = array("Name of the database")

      '=== array to put in table, choice button, header, middle line, bottom line, reload
      a = dynbotcho(fmid, "choose the database to edit", aratit, ara01, 1 ,1, 1, 1, 1, 0,"mid")
   
      do
         wscript.sleep 100
   
         '=== while we wait for input value (or button press), user can press "escape" key, "cancel" button or close internet explorer
         if resbutmidstr="cancel" or reskeymid=27 or bready=true or resbutlefstr<>"" then
            '=== if user pressed escape or cancel, we clear the frames
            if resbutmidstr="cancel" or reskeymid=27 then
               a = clefra(array("fmid","fbot"))
               resbutmidstr="cancel"
            end if
            exit do
         end if  
   
      loop while resbutmidstr=""
   
      if bready=false and resbutlefstr="" and reskeymid<>27 and resbutmidstr<>"cancel" then
       
         '=== convert the choice made with the button to a number (remove "but" from left side)
         a=right(resbutmidstr,len(resbutmidstr)-3)
         resbutmidstr=""
         '=== get the array that contain the choice in dbnam (database name)
         dbnam=ara01(a-1)
       
         '=== open the database
         Set objcat = CreateObject("ADOX.Catalog")
         Set objcon = nothing
         Set objcon = CreateObject("ADODB.Connection")
       
         constr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & dbnam
         objcon.open constr
         objcat.activeconnection=(objcon)
       
         '=== pressing left control button while in a function will call a sub make internet explorer crash
         '=== so i have to put the table choice in main loop, cant do a sub

         '=== choose the table to edit

         a = clefra(array("fmid","fbot"))
       
         aratit=array("Table name")
         x=0
         redim ara01(0)
         for each tab in objcat.Tables
            If tab.Type = "TABLE" Then
               c = lcase(tab.name)
               redim preserve ara01(x)
               ara01(x)=c
               x=x+1
            end if
         next
         
         a = dynbotcho(fmid, "Choose the table to edit", aratit, ara01, 1 ,1, 1, 1, 1, 0, "mid")
   
         do
            wscript.sleep 100
   
            '=== while we wait for input value (or button press), user can press "escape" key, "cancel" button or close internet explorer
            if resbutmidstr="cancel" or reskeymid=27 or bready=true or resbutlefstr<>"" then
               '=== if user pressed escape or cancel, we clear the frames
               if resbutmidstr="cancel" or reskeymid=27 then
                  a = clefra(array("fmid","fbot"))
                  resbutmidstr="cancel"
               end if
               exit do
            end if  
       
         loop while resbutmidstr=""

         if bready=false and resbutlefstr="" and reskeymid<>27 and resbutmidstr<>"cancel" then
       
            '=== convert the choice made with the button to a number (remove "but" from left side)
            a=right(resbutmidstr,len(resbutmidstr)-3)
            resbutmidstr=""
            '=== get the array that contain the choice in dbnam (database name)
            tabnam=ara01(a-1)
         
            for each tab in objcat.Tables
               If tab.Type = "TABLE" Then
                  if tabnam = lcase(tab.name) then set objtab=tab
               end if
            next
         
            '=== count of the lines to separate them for edition 20 or 50 at one time
            sql = "select count(*) as nbrlin from " & tabnam
            a = exesql(objcon,tag,sql)
         
            '=== total number of records
            totrec=tag("nbrlin")
         
            '=== get all column names
            sql = "select top 1 * from " & tabnam
            a = exesql(objcon,tag,sql)
         
            coltot=0
            redim aratit(coltot)
            For Each a In TAG.fields
               '=== columns names
               redim preserve aratit(coltot)
               aratit(coltot)=Trim(a.Name)
               coltot=coltot+1
            Next
            coltot=coltot-1
         
            '=== chek for primary key in table
            prikeycolnam=""
            prikeygndmul=0 '=== multiple column primary key found
            for each objind in objtab.indexes
               If objind.PrimaryKey = True Then
                  a=""
                  For i = 0 To objind.Columns.Count - 1
                     a=a & objind.Columns(i).Name
                  Next
               
                  if i=1 then
                     '=== primary key column name if its related to one column only
                     prikeycolnam=a
                     if logall=1 then
                        fil02.WriteLine date & " " & time & " Primary column existing: " & prikeycolnam
                        'fil02.WriteLine date & " " & time & " Autoincrement status: " & objcol.Properties("AutoIncrement")
                     end if
                  else
                     if i>1 then prikeyfndmul=1
                  end if
               end if
            next          
         
            '=== chek if there is an auto increment column to be able to edit limited results at one time
            fnd01=0 '=== found autoincrement column
            fnd02=0 '=== found a column named codint
            for each objcol in objtab.columns
               c=lcase(objcol.name)
               d=objcol.Properties("AutoIncrement")
               if d<>false then
                  codint=objcol.name
                  if lcase(codint)="codintsef" then fnd02=1
                  fnd01=1
                  if logall=1 then
                     fil02.WriteLine date & " " & time & " Column existing: " & c
                     fil02.WriteLine date & " " & time & " Autoincrement status: " & objcol.Properties("AutoIncrement")
                  end if
               end if
               '=== aef
               'if logall=1 then
                  'fil02.WriteLine date & " " & time & " Column existing: " & c
                  'fil02.WriteLine date & " " & time & " Autoincrement status: " & objcol.Properties("AutoIncrement")
               'end if
                  'fmid.WriteLn("column existing: " & c & "&nbsp&nbsp&nbspautoincrement status: " & objcol.Properties("AutoIncrement") & "<br>")
            next
         
            '=== close the last query to be able to create a new table autoincrement
            set tag=nothing
         
            '=== create a autoincrement integer column called "codint"
            '=== to be able to edit limited results at one time (let's say 50 at a time)
            colaut="codintsef"
            if prikeycolnam="" then
               if fnd01=0 then
                  if fnd02=0 then
                     'fmid.WriteLn("no codint (Auto increment column)")
                     colnam="codintsef"
                     a=crecol(objtab,colnam)
                     coltot=coltot+1
                     redim preserve aratit(coltot)
                     aratit(coltot)=colnam
                     '=== make it a primary key, but not if there is a multiple column primary key present
                     if prikeyfndmul=0 then
                        Set objkey = CreateObject("ADOX.key")
                        objkey.name="Primary"
                        objkey.columns.append colnam
                        objtab.keys.append objkey
                        if logall=1 then
                           fil02.WriteLine date & " " & time & " created a primary column for result selecting " & colnam
                           'fil02.WriteLine date & " " & time & " Autoincrement status: " & objcol.Properties("AutoIncrement")
                        end if
                     end if
                  else
                     fmid.WriteLn("cannot create a auto increment column named" & colaut)
                     fmid.WriteLn("multiple page edition will be desactivated")
                     fmid.WriteLn("some loading might be slow")
                  end if
               end if
               prikeycolnam=colnam
            end if
         
            'sql = makque(symptom,tab,sel,whe," order by [probabilité] DESC","LIKE","%")
         
            '================================
            '=== loop to edit x at one time
         
            '=== 50 record at one time
            '=== totrec = maximum
            '=== actrec = actual record where we are (page moving)
            actrec=0
         
            '=== COMPONENT = words to search (separated by a space)
            tab = 1 '=== table to seach in    (alltab)
            sel = 1 '=== columns to list      (allara)
            whe = 0 '=== columns to search in (Allara)
         
            '=== test purpose
            component = ""
         
            sql = makque(component,tab,sel,whe,"","LIKE","%")

            '=== count of the lines to separate them for edition 20 or 50 at one time
            'sql = "select count(*) as nbrlin from " & tabnam
            'a = exesql(objcon,tag,sql)
         
            '=== total number of records
            'totrec=tag("nbrlin")
         
            'sql = "select * from " & tabnam & " where [component] like '%HOSE%'"
            '=== this will be used only if the table is really big
            '=== if table is not so big we can put it in the array and edit values by small pack
            '=== se we dont need fewer results, since it will fit the array
            ' & " where " & prikeycolnam & ">" & actrec
            if logall=1 then
               fil02.WriteLine date & " " & time & " QUERY: "
               fil02.WriteLine sql
               'fil02.WriteLine date & " " & time & " Autoincrement status: " & objcol.Properties("AutoIncrement")
            end if
            a = exesql(objcon,tag,sql)
         
            if tag.eof=0 then
               myarray=TAG.GetRows()
            else
               redim myarray(coltot,0)
               'fbot.WriteLn("<br>total columns: " & coltot & "<br>")
               for i=0 to coltot
                  myarray(i,0)="ERROR there was 0 record in this query"
               next
               fbot.WriteLn("<br>ERROR<br>" & sql & "<br>gave 0 results<br>")
            end if
         
            '=== total of records (max y in array if there is a x only)
            totrec = cnttotrec(myarray)
         
            if logall=1 then
               fil02.WriteLine date & " " & time & " total records: " & totrec+1
            end if
         
            offset=0
            search=""
            aratit = allara(tab,sel)
            a = dynbotcho(fbot, tabnam, aratit, myarray, 1 ,1, 1, 1, 1, edtmod,"bot")

            do
               wscript.sleep 100
   
               '=== while we wait for input value (or button press), user can press "escape" key, "cancel" button or close internet explorer
               if resbutbotstr="cancel" or reskeymid=27 or bready=true then
               '=== if user pressed escape or cancel, we clear the frames
                  if resbutmidstr="cancel" or reskeymid=27 then
                     a = clefra(array("fmid","fbot"))
                     resbutmidstr="cancel"
                  end if
                  exit do
               end if
             
               if resbutbotstr="Precedent" then
                  a=offset
                  offset=offset-maxoff
                  offset=max(0,offset)
                  resbutbotstr=""
                  if offset<>a then
                     '=== totrec total number of record (displayed at end of first line)
                     '=== maxoff maxiumm number of row in a page
                     '=== offset page flip number (multiple of maxoff)
                     a = dynbotcho(fbot, tabnam, aratit, myarray, 1 ,1, 1, 1, 1, edtmod,"bot")
                  end if
               end if            
             
               if resbutbotstr="Next" then
                  a=offset
                  offset=offset+maxoff
                  if offset>totrec then offset=offset-maxoff
                  resbutbotstr=""
                  if offset<>a then
                     a = dynbotcho(fbot, tabnam, aratit, myarray, 1 ,1, 1, 1, 1, edtmod,"bot")
                  end if
               end if
             
               if resbutbotstr="Search" then
               
                  strsearch=fbot.form01.boxsearch.Value
                  strsearch=lcase(strsearch)
               
                  '=== make a dynamic query to search for every words in every columns
                  'makque(ssea, ttab, sselect,wwhere, ssufix,ooper,wwild)
                  component = strsearch
         
                  sql = makque(component,tab,sel,whe,"","LIKE","%")
         
                  if logall=1 then
                     fil02.WriteLine date & " " & time & " QUERY: "
                     fil02.WriteLine sql
                     'fil02.WriteLine date & " " & time & " Autoincrement status: " & objcol.Properties("AutoIncrement")
                  end if
                  a = exesql(objcon,tag,sql)
         
                  if tag.eof=0 then
                     myarray=TAG.GetRows()
                  else
                     redim myarray(coltot,0)
                     'fbot.WriteLn("<br>total columns: " & coltot & "<br>")
                     for i=0 to coltot
                        myarray(i,0)="ERROR there was 0 record in this query"
                     next
                     fbot.WriteLn("<br>ERROR<br>" & sql & "<br><br>gave 0 results<br>")
                  end if
               
                  offset=0
                  totrec = cnttotrec(myarray)
                  if logall=1 then
                     fil02.WriteLine date & " " & time & " total records: " & totrec+1
                  end if
                  a = dynbotcho(fbot, tabnam, aratit, myarray, 1 ,1, 1, 1, 1, edtmod,"bot")
               
                  resbutbotstr=""
               end if
             
               if  resbutlefstr<>"" then
                  '=== save the line selected
                  exit do
                  resbutlefstr=""
               end if            
             
            loop while resbutbotstr=""

            if bready=false and resbutlefstr="" and reskeymid<>27 and resbutmidstr<>"cancel" then
             
               '=== a line was selected or we change page
               fbot.WriteLn(resbutbotstr)
             
            end if
         
            '=== save done
         
         end if

      end if
   
      'msgbox("exit on left button" & resbutlefstr)
      'resbutlefstr = ""
      resbutmidstr = ""
      resbutbotstr = ""
      reskeylef = 0
      reskeymid = 0
      reskeybot = 0
   
   end if
 
   '=== .1 seconds
   wscript.sleep 50
 
'=== we loop until internet explorer was closed or the quit button was pressed
loop until bReady or resbutlefstr="quit01"

'======================
'====================== end of main loop
'======================

'=== someone pressed "quit" on left frame (control frame, flef object)

'=== at the end, if internet explorer was not closed, we close it
if bready=false then
   oie.quit
   set oie=nothing
end if
if logall=1 then
   fil02.WriteLine date & " " & time & " END"
end if
if logall = 1 then
   fil02.close
end if

'=== we end wscript.exe, exiting all running code interpretation
wscript.quit

'==================================================================================================

'=== many subs

'=== if internet explorer is closed (event) we change bready value to TRUE
sub IE_onQuit()
   bReady=true
end sub


'============================================== subs and functions ====================================

'=== frames clear content by navigating to a blank
'=== input is an array containing name of frames as "flef" = frame left
'=== this sub generate a code and execute it in a string (cc)
'=== fully dynamic programming at it's best ;)
function clefra(aara)


For Each afra In aara
intfra = Int(InStr("fleffmidfbot", afra) / 4)
'•uninitialized - Has not started loading yet
'•loading - Is loading
'•interactive - Has loaded enough and the user can interact with it
'•complete - Fully loaded
fraara = array("left","middle","bottom")

set tmpfra = crefra(fraara(intfra))

'tmpfra.writeln(
htmtab = "<input type=""hidden""/>&nbsp;"
'Call wrifra(tmpfra, htmtab)
tmpfra.writeln(htmtab)
Call fready(tmpfra)

Call relfra(tmpfra)
tmpfra.location.reload(True)
Call fready(tmpfra)

htmtab = ""

'=== backgrounds
'fraara(0) = ("<body background=""" & BASEDIR & "images_interface\fond_gauche.jpg"">")
        'fraara(1) = ("<body background=""" & BASEDIR & "images_interface\fond_gris.jpg"">")
        'fraara(2) = ("<body background=""" & BASEDIR & "images_interface\fond_gris.jpg"">")
'For Each astr In fraara(intfra)
' htmtab = htmtab & astr
'Next
tmpfra.writeln(htmtab)
Call fready(tmpfra)
Next

resbutlefstr = ""
resbutmidstr = ""
resbutbotstr = ""
reskeylef = 0
reskeymid = 0
reskeybot = 0


end function

Function crefra(ffranam)
 
'Dim ffra As Object
err01 = 0
try01 = 0
ffra = ""
maxerr = 60 '=== 3 sec before fatal error

try01 = 1
fileversion = objFSO.GetFileVersion("C:\program files\internet explorer\iexplore.exe")
finddot = instr(fileversion,".")
fileversion2 = left(fileversion,finddot-1)

If logall = 1 Then fil02.WriteLine(DateValue(Now) & " " & TimeValue(Now) & " " & ffranam)

if fileversion2 = "10" or fileversion2 = "11" then
'=== ie10 frame access
'set crefra = oIE.parent.Document.frames.item(ffranam).document
set crefra = oie.parent.document.getElementByid(ffranam).contentdocument
else
set crefra = oie.document.frames(ffranam).document
end if


'ffra = oIE.Document.frames.item(ffranam).document

'If logall = 1 Then fil02.WriteLine(DateValue(Now) & " " & TimeValue(Now) & " crash creating frame again ")

End Function

Sub relfra(ffra)

ffra.location.reload(false)
'If logall = 1 Then fil02.WriteLine(DateValue(Now) & " " & TimeValue(Now) & " error reloading frame dynbotcho")

End Sub

Sub fready(tmpfra)
' Dim err01 As Integer = 0
' Dim reasta As Integer
' Dim try01 As Integer = 0
' Do
' Try


' reasta = tmpfra.getElementsByTagName("input").length
'If logall = 1 Then fil02.WriteLine(DateValue(Now) & " " & TimeValue(Now) & " ---------------- found tag input" & reasta)
' Do Until reasta > 0
' System.Threading.Thread.Sleep(10)
' If logall = 1 Then fil02.WriteLine(DateValue(Now) & " " & TimeValue(Now) & " ---------------- found tag input")
' reasta = tmpfra.getElementsByTagName("input").length
' Loop
' try01 = 1
' err01 = 0
' Catch ex As Exception
' err01 = err01 + 1
' try01 = 0
' System.Threading.Thread.Sleep(50)
' End Try
' If err01 = 0 Or try01 = 1 Then Exit Do
' Loop Until err01 > 10

' If err01 > 10 Then If logall = 1 Then fil02.WriteLine(DateValue(Now) & " " & TimeValue(Now) & " ERROR accessing frame: " & err01)
End Sub

function clefraold(aara)
 
   cc=""
   for each aa in aara
      'cc = cc & "Do While (oIE.Busy)" & vbcrlf
      'cc = cc & "   wscript.sleep 200" & vbcrlf
      'cc = cc & "Loop" & vbcrlf
      'cc = cc & "Do While oie.readystate<>4" & vbcrlf
      'cc = cc & "   wscript.sleep 200" & vbcrlf
      'cc = cc & "Loop" & vbcrlf
      'cc = cc & aa & ".location.reload(true)" & vbcrlf
      'cc = cc & "Do While (oIE.Busy)" & vbcrlf
      'cc = cc & "   wscript.sleep 200" & vbcrlf
      'cc = cc & "Loop" & vbcrlf
      'cc = cc & "Do While oie.readystate<>4" & vbcrlf
      'cc = cc & "   wscript.sleep 200" & vbcrlf
      'cc = cc & "Loop" & vbcrlf
      'cc = cc & aa & ".WriteLn(""&nbsp;"")" & vbcrlf
      'cc = cc & aa & ".location.reload(true)" & vbcrlf
      'cc = cc & "Do While oie.readystate<>4" & vbcrlf
      'cc = cc & "   wscript.sleep 200" & vbcrlf
      'cc = cc & "Loop" & vbcrlf
      'cc = cc & "Do While (oIE.Busy)" & vbcrlf
      'cc = cc & "   wscript.sleep 200" & vbcrlf
      'cc = cc & "Loop" & vbcrlf
      'cc = cc & "Do until " & aa & ".ReadyState = ""Terminé"" or " & aa & ".ReadyState = ""Complete""" & vbcrlf
      'cc = cc & "   wscript.sleep 200" & vbcrlf
      'cc = cc & "Loop" & vbcrlf
   
      '•uninitialized - Has not started loading yet
      '•loading - Is loading
      '•interactive - Has loaded enough and the user can interact with it
      '•complete - Fully loaded


      htmtab=""
      if aa = "flef" then
         aa = lcase(flef.readystate)
         do until aa="complete" or aa="terminé" or aa="interactive"
            if logall=1 then fil02.writeline "*********************************** readystate of flef: " & aa
            wscript.sleep 100
            aa = lcase(flef.readystate)
         loop
         htmtab = htmtab & "&nbsp;"
         aa = lcase(flef.readystate)
         do until aa="complete" or aa="terminé" or aa="interactive"
            if logall=1 then fil02.writeline "*********************************** readystate of flef: " & aa
            wscript.sleep 100
            aa = lcase(flef.readystate)
         loop
         for each a in lefara
            htmtab = htmtab & a
         next
         flef.writeln(htmtab)
         flef.location.reload(true)
         aa = lcase(flef.readystate)
         do until aa="complete" or aa="terminé" or aa="interactive"
            if logall=1 then fil02.writeline "*********************************** readystate of flef: " & aa
            wscript.sleep 100
            aa = lcase(flef.readystate)
         loop    
      end if
   
      if aa = "fmid" then
         aa = lcase(fmid.readystate)
         do until aa="complete" or aa="terminé" or aa="interactive"
            if logall=1 then fil02.writeline "*********************************** readystate of fmid: " & aa
            wscript.sleep 100
            aa = lcase(fmid.readystate)
         loop
         htmtab = htmtab & "&nbsp;"
         aa = lcase(fmid.readystate)
         do until aa="complete" or aa="terminé" or aa="interactive"
            if logall=1 then fil02.writeline "*********************************** readystate of fmid: " & aa
            wscript.sleep 100
            aa = lcase(fmid.readystate)
         loop
         for each a in midara
            htmtab = htmtab & a
         next
         fmid.writeln(htmtab)
       
         fmid.location.reload(true)
         aa = lcase(fmid.readystate)
         do until aa="complete" or aa="terminé" or aa="interactive"
            if logall=1 then fil02.writeline "*********************************** readystate of fmid: " & aa
            wscript.sleep 100
            aa = lcase(fmid.readystate)
         loop
         if logall=1 then fil02.writeline "mid frame cleared----------- ccc -----------"                    
      end if
   
      if aa = "fbot" then
         aa = lcase(fbot.readystate)
         do until aa="complete" or aa="terminé" or aa="interactive"
            if logall = 1 then fil02.writeline "*****************111****************** readystate of fbot: " & aa
            wscript.sleep 100
            aa = lcase(fbot.readystate)
         loop
         htmtab = htmtab & "&nbsp;"
         aa = lcase(fbot.readystate)
         do until aa="complete" or aa="terminé" or aa="interactive"
            if logall = 1 then fil02.writeline "*****************222****************** readystate of fbot: " & aa
            wscript.sleep 100
            aa = lcase(fbot.readystate)
         loop
         for each a in midara
            htmtab = htmtab & a
         next
         fbot.writeln(htmtab)
       
         fbot.location.reload(true)
         aa = lcase(fbot.readystate)
         do until aa="complete" or aa="terminé" or aa="interactive"
            if logall = 1 then fil02.writeline "*****************333****************** readystate of fbot: " & aa
            wscript.sleep 100
            aa = lcase(fbot.readystate)
         loop                
      end if
   
   next

   'execute cc
 
   '=== we also clear the variables used to control the action buttons and the key pressed in each frames
   '=== so the action wont be taken twice (or infinitly) in the main loop
 
   'set flef = oie.document.frames("left").document
   'set fmid = oie.document.frames("middle").document
   'set fbot = oie.document.frames("bottom").document
 
'for i=0 to ubound(arabutnam)
'   flef.forms(0).elements(arabutnam(i)).onclick = getref("buttonlef")
'next

'=== we also chek the key presse in each frame
'=== we do this cause we want "enter" key to be used instead of pressing "ok" button with the mouse
'set flef.onkeypress = GetRef("Checklef")
'set fmid.onkeypress = GetRef("Checkmid")
'set fbot.onkeypress = GetRef("Checkbot")

   resbutlefstr = ""
   resbutmidstr = ""
   resbutbotstr = ""
   reskeylef = 0
   reskeymid = 0
   reskeybot = 0

end function

'=== form dynamically generated =========================================================================

function dynforgen (distmp, namtmp,deftmp,typtmp,errtmp,buttmp,title)
 
   '=== generate a form for input in the input frame (fmid object)
   '=== focus on the first field with no default value
   '=== display suffix message in red if "error" (or "erreur" - french) keyword is in it
   htmtab=""
 
   for each a in midara
      htmtab = htmtab & a
   next
 
   htmtab = htmtab & "<h3><span class=SpellE>" & title & "</span></h3>"
   '=== default focus on empty field (with no default value)
   deffoc=0
   for ii=0 to ubound(namtmp)
      if deftmp(ii)="" then
         if instr(lcase(errtmp(ii)),"facultatif")=0 then
            htmtab = htmtab & "<BODY onLoad=""document.form01." & namtmp(ii) & ".focus()"">"
            deffoc=1
         end if
      end if
      '=== no default value empty, we focus on first field
   next
   if deffoc=0 then
      htmtab = htmtab & "<BODY onLoad=""document.form01." & namtmp(0) & ".focus()"">"
   end if
   htmtab = htmtab & "<div class=MsoNormal align=center style='text-align:center'>"
   htmtab = htmtab & "</div>"

   htmtab = htmtab & "<form name=form01>"

   '=== button and error message
   for ii=0 to ubound(namtmp)

      htmtab = htmtab & distmp(ii) & ": "

      '=== we disable "enter" to submit form because we manage this event as a onkeypress in the parent frame of the form later
      '=== we had to do this, because the web page form is not run on a server, and the web page dont have control, the VBS script outside the page have control
   
      htmtab = htmtab & "<input type=""" & typtmp(ii) & """ id=" & namtmp(ii) & " NAME=""" & namtmp(ii) & """ size=""" & max(20,len(deftmp(ii))) & """ value=""" & deftmp(ii) & """ onKeypress=""return event.keyCode!=13"""
      'fmid.WriteLn("")
      if instr(lcase(errtmp(ii)),"error")<>0 or instr(lcase(errtmp(ii)),"erreur")<>0 then
         col="red"
      else
         col="blue"
      end if
      htmtab = htmtab & "&nbsp; <b><span style='color:" & col & "'>&nbsp" & errtmp(ii) & "</span></b><br style='mso-special-character:line-break'>"
   next

   htmtab = htmtab & "<![if !supportLineBreakNewLine]><br style='mso-special-character:line-break'>"
   htmtab = htmtab & "<![endif]></p>"
 
   for ii=0 to ubound(buttmp)
      typ01 = "button"
      htmtab = htmtab & "<input type=""" & typ01 & """ name=""" & buttmp(ii) & """ value=""&nbsp;" & buttmp(ii) & "&nbsp;"">"
      htmtab = htmtab & "&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp"
   next
 
   htmtab = htmtab & "</div>"
   htmtab = htmtab & "</form>"
   htmtab = htmtab & "</body>"
   htmtab = htmtab & "</html>"
   fmid.writeln htmtab
   fmid.location.reload(true)

   '=== wait for internet explorer to be ready after we refresh the page with the new form
   for ii=0 to ubound(buttmp)
      Do While (oIE.Busy)
         wscript.sleep 100
      loop
      do while oie.readystate<>4
         wscript.sleep 100
      Loop
      '=== value to return for each button in the form
      fmid.forms(0).elements(buttmp(ii)).onclick = getref("buttonmid")
   next
 
   '=== regenerate the event that call a sub if a button is pressed
   set fmid.onkeypress = GetRef("Checkmid")
 
   '=== clear button pressed and key pressed for this frame
   resbutmidstr=""
   reskeymid=0
end function

'===  max
Function max(a, b)
If a > b Then max = a Else max = b
End Function

function crewebmai(oie, doctit, maitit, arabutnam, arabutdes, aradepnam, aradepcol)

'=== create an internet explorer object (oie) that will be in 3 frames (flef, fmid, fbot), acting at the main interface for all this program

oie.FullScreen = False
'.ToolBar   = False
'.StatusBar = False
'.Navigate("About:Blank")
'.visible = true

oIE.left=0 ' window position
oIE.top = 0 ' and other properties
'.ParentWindow
'        .resizeto 640,300
'        .moveto (.screen.width
oIE.height = 500
oIE.width = 500
oIE.menubar = 1 '=== no menu
oIE.toolbar = 1
oIE.statusbar = 1
oIE.RegisterAsDropTarget = True
oie.Navigate("about:blank")
'oie.Navigate("about:tabs")
oie.document.title = doctit
oiewid = oie.document.parentwindow.screen.width
oiehei = oie.document.parentwindow.screen.height
sizwidpercent = 100
sizheipercent = 95
loswid = 100-sizwidpercent
loshei = 100-sizheipercent
newwid = oiewid*sizwidpercent*.01
newhei = oiehei*sizheipercent*.01
oie.document.parentwindow.resizeto newwid,newhei
newx = oiewid * loswid * .01 /2
newy = oiehei * (loshei/2) * .01 /2
oie.document.parentwindow.moveto newx, newy
oIE.visible = 1 '=== visible on
oie.addressbar=false

'=== we will always have 3 frames, control, input and output (flef, fmid, fbot)
'=== used an array to have a good view of the line of html and possibility to add something else easily

aratmp=array(_
"<HTML>",_
"<HEAD><TITLE>" & doctit & "</TITLE>",_
"<meta content=""text/html; charset=utf-8"" http-equiv=""Content-Type"">",_
"<meta http-equiv=""X-UA-Compatible"" content=""IE=8"">",_
"</HEAD>",_
"<FRAMESET id='main' COLS=""13%, *"">",_
"<FRAME SRC=""About:Blank"" NAME=""left"" id=""left"">",_
"<frameset id='main2' rows=""30%,70%"">",_
"<FRAME SRC=""About:Blank"" NAME=""middle"" id=""middle"">",_
"<FRAME SRC=""About:Blank"" NAME=""bottom"" id=""bottom"">",_
"</FRAMESET>", _
"</frameset>", _
"</HTML>")

'oie.Navigate("About:Blank")

'=== send the array content in internet explorer to create 3 frames
for i = 0 to UBound(aratmp, 1)
  oie.document.WriteLn(aratmp(i))
next

oie.refresh

Do While (oIE.Busy)
  wscript.sleep 50
Loop

'=== wait till document loaded
do while oie.readystate<>4
  wscript.sleep 50
Loop

'=== vista activate
'=== make internet explorer the main active window
a = objShe.AppActivate("http:/// - " & doctit & " - M")
a = objShe.AppActivate(doctit & " - M")

'=== theses objects are used to send data to the 3 different frames
'=== if you dont define them as object, the access to them is very slow when we use the names instead of the objects

'=== object used to write in a frame with writeln
fileversion = objFSO.GetFileVersion("C:\program files\internet explorer\iexplore.exe")
finddot = instr(fileversion,".")
fileversion2 = left(fileversion,finddot-1)

if fileversion2 = "10" or fileversion2 = "11" then
'=== ie10 frame access
set flef = oie.parent.document.getElementByid("left").contentdocument
set fmid = oie.parent.document.getElementByid("middle").contentdocument
set fbot = oie.parent.document.getElementByid("bottom").contentdocument
else
set flef = oie.document.frames("left").document
set fmid = oie.document.frames("middle").document
set fbot = oie.document.frames("bottom").document
end if

'=== object used to navigate an empty page in a frame
'set flefl = oie.document.frames("left").location
'set fmidl = oie.document.frames("middle").location
'set fbotl = oie.document.frames("bottom").location

'=== string result for a button press in a frame (lef = left frame, mid = middle frame (up))
resbutlefstr=""
resbutmidstr=""
resbutbotstr=""

reskeylef=0
reskeymid=0
reskeybot=0

'=== all the chek to be made in first page (1 at the moment, since ready have many values)

nbrbut=UBound(arabutnam, 1)
redim buttag(nbrbut)
form = "flef"

flef.WriteLn("<html><body>")
flef.WriteLn("<body background=""" & basedir & "images_interface\fond_gauche.jpg"">")
flef.WriteLn("<h3><span class=SpellE>" & maitit & "</span></h3>")
flef.WriteLn("<form name='form1'>")

'(1) Where you want the image to appear: <span id="image"></span>

'(2) Get a reference to it: var e = document.getElementById('image');

'(3) Insert the img HTML code into the span: e.innerHTML = '<img src="./images/your_picture.jpg" />';

'aa = """file:///" & basedir & "PhotoHydComponent\002-00_HydroCraft_HC-EC_EndCover.jpg"""
'aa = "'" & basedir & "PhotoHydComponent\002-00_HydroCraft_HC-EC_EndCover.jpg'"
'aa = """./test.jpg"""
'aa = replace(aa,"\","/")
htmtab = ""
'htmtab = htmtab & "<img src=" & aa & " alt=" & aa & " />"

fmid.location.reload(true)
'msgbox(htmtab)
'oie.document.getElementById("middle").document.body.innerhtml = htmtab
'document.getElementById("myiframe").contentWindow.document.body.innerHTML = "<input type='button' value='Click' onclick='parent.buttonClick()'>";
'<script type="text/javascript">


'<script type="text/javascript">
'function chanceImage() {
'document.getElementById('image).innerHTML = '<img src="image.png" alt="Image" border="0">';
'}
'</script>

'htmtab = ""
'htmtab = htmtab & "<script type=""text/javascript"">"
'htmtab = htmtab & "document.getElementById(""middle"").contentWindow.document.body.innerHTML = '<img src=" & aa & " alt=""Image"" border=""0"">';"
'htmtab = htmtab & "</script>"

'fmid.writeln htmtab
'fmid.location.reload(true)

'=== removed 2015-10-25
'oie.document.getElementById("middle").contentWindow.document.body.innerhtml = htmtab

'fmid.location.reload(true)

for i=0 to ubound(arabutnam)

  '=== convert xls to mdb button appear for stas only

  if ((usenam="wildboy" or usenam="fournier.serge" or usenam="fortin.jp" or usenam="lavoie.daniel" or usenam="doucet.gm") and arabutnam(i)="excel2mdb") or arabutnam(i)<>"excel2mdb" then

 'style="background-color: #cc0000; color: #ffffff;" /
 b = "<input type=""button"" style=""height:50px;font-size:14px;width:100%;"" name=""" & arabutnam(i) & """ value=""" & arabutdes(i) & """"
 i2=i
 if i>ubound(aradepnam) then
i2=ubound(aradepnam)
 else
a=aradepnam(i2)
 end if

 if a<>lasdep then
'=== new departement name
flef.WriteLn( "<br>" & a & "<br>")
lasdep=a    
 end if
 b = b & " style=""background-color: #" & aradepcol(i2) & "; color: #000000;""><br>"
 flef.WriteLn(b)
  end if
next

flef.WriteLn("</form>")
flef.WriteLn("</body>")
flef.WriteLn("</html>")

'=== we dont refresh this frame, its the first one

end function

'=== sub to call when something is pressed
'=== called for many buttons, return the button name or a keyboard code (Ascii)
sub buttonlef
   set src = flef.parentWindow.event.srcElement
   resbutlefstr = src.name
end sub

sub buttonmid
   set src = fmid.parentWindow.event.srcElement
   resbutmidstr = src.name
end sub

sub buttonbot
   set src = fbot.parentWindow.event.srcElement
   resbutbotstr = src.name
end sub

sub Checklef
   reskeylef = flef.parentWindow.event.keycode
end sub

sub Checkmid
   reskeymid = fmid.parentWindow.event.keycode
end sub

sub Checkbot
   reskeybot = fbot.parentWindow.event.keycode
end sub

'=== unblur
sub onblurlef
   set src = flef.parentWindow.event.srcElement
   resblulefstr = src.name
   resblulefval = src.value
   resblulefid = src.id
end sub

sub onblurmid
   set src = fmid.parentWindow.event.srcElement
   resblumidstr = src.name
   resblumidval = src.value
   resblumidid = src.id
end sub

sub onblurbot
   set src = fbot.parentWindow.event.srcElement
   resblubotstr = src.name
   resblubotval = src.value
   resblubotid = src.id
end sub


'=== chek in the actual folder if a file exist
function filsea(filname)

'=== chek also actual folder for a "Rappel_LOG" file (instr)
Set objFolder2 = objFSO.GetFolder(basedir)'=== dir
Set objFiles2 = objFolder2.files '=== fichiers

found=0  '=== fichier de rapport pas trouve
For Each objFile3 in objFiles2
  nomfile =objfile3.name
  nomfile= lcase(nomfile)

next


end function

'=== delete a table in a database

function tabdel()
       
         for each tab in objcat.Tables
            If tab.Type = "TABLE" Then
               b=lcase(tab.name)
               '=== object.delete not supported, so we delete with name
               objcat.tables.delete b
               fbot.WriteLn("delete: " & b & "<br>")
            END IF
         next

end function

'=== for reference
function dynbotcho00
i3=0
For each dia01 in choiceara
 sql = makque(dia01,tab,sel,whe,"","=","")
 a = exesql(objcon,tag,sql)

 '=== make same array for a multiples queries
 if tag.eof=0 then
'a = dynbotcho("DIAGNOSTIC",tag,0,sql,1,1,1,1) '=== 1 2 3
if ubound(choiceara)=0 and i3=0 then
a = dynbotcho("DIAGNOSTIC",tag,0,sql,1,1,1,1) '=== 1 2 3
elseif i3=0 then
'=== header
a = dynbotcho("DIAGNOSTIC",tag,0,sql,1,1,0,0) '=== 1 2 3
elseif i3<>ubound(choiceara) and i3<>0 then
'=== footer
a = dynbotcho("DIAGNOSTIC",tag,0,sql,0,1,0,0) '=== 1 2 3
elseif i3=ubound(choiceara) then
a = dynbotcho("DIAGNOSTIC",tag,0,sql,0,1,1,1) '=== 1 2 3
end if
i3 = i3 + 1
 else
'=== 0 results
a = nores(sql)
 end if
next
end function

function dynbotcho(ffra, ttext, aaratit, aara, cc01 ,hh, mm, ff, rr, ttxtbox,ffranam)
   '=== ffra frame to use for display (object)
   '=== ttext to display
   '=== aara = array with what to display
   '=== cc01 = choice button (no choice button when we display disgnostics, cause of multiple tables in one)
   '=== sql = sql query for debugging
   '=== hh = 1 = header
   '=== mm = 1 = middle
   '=== bb = 1 = footer
   '=== rr = 1 = reload at end
   '=== ttxtbox = all data are in a textbox so we can edit them (1) no date in text box (0)
   '=== ffranam = frame name
 
   htmtab = ""
   if ffranam = "lef" then
      for each a in lefara
         htmtab = htmtab & a
      next
   end if
   if ffranam = "mid" then
      for each a in midara
         htmtab = htmtab & a
      next
   end if
   if ffranam = "bot" then
      for each a in botara
         htmtab = htmtab & a
      next
   end if

   if logall = 1 then fil02.writeline "--- the sub dynbotcho has been called"
 
   call oieready
   '=== print button
   priara = array("<input type=""button"" onClick=""javascript:print()"" value=""Print""/>")
 
   xmax = UBound(aara, 1) 'Returns the Number of columns  --- elements in first dimension
   'on error resume next
   on error resume next
   '=== chek the number of elements in second dimension, if there is none, then the array is only a list with 1 column
   ymax = UBound(aara, 2) 'Returns the Number of rows     --- elements in second dimension
 
   '=== number of dimensions in case there is only 1 column
   if err<>0 then
      dimnum=1
      if logall=1 then
         fil02.WriteLine date & " " & time & " max column: " & xmax
      end if
   else
      dimnum=2
      if logall=1 then
         'fil02.WriteLine date & " " & time & " max column: " & xmax
         fil02.WriteLine date & " " & time & " max row   : " & ymax
         'fil02.WriteLine date & " " & time & " offset    : " & maxoff
         'fil02.WriteLine date & " " & time & " offsetnow : " & offset
      end if
   end if
   on error goto 0
 
   if dimnum=2 then
      if totrec>=maxoff then ymax=maxoff+offset-1
      if ymax>totrec then ymax=totrec
      'if ymax>maxoff then ymax=maxoff
   end if
   '=== web script for buttons to return the number of the button that was pressed
   htmtab = htmtab & "<form name=form01>"
   '=== print button
   if hh=1 then
      for each a in priara
         htmtab = htmtab & a
         'if logall=1 then fil02.writeline "*-------============*"
         'ffra.WriteLn("<BODY onLoad=""document.form01." & namtmp(0) & ".focus()"">")
      next
      if cc01=0 then htmtab = htmtab & "<br><br>"
   end if

   '=== search button only if bottom frame
   if ffranam="bot" and cc01<>0 then
      strsearch=""
      'fmid.WriteLn("    <input type=""" & typtmp(ii) & """           id=" & namtmp(ii)NAME=""" & namtmp(ii) & """ size=""" & max(20,len(deftmp(ii))) & """ value=""" & deftmp(ii) & """ onKeypress=""return event.keyCode!=13""")
      if secseatag=1 then
         htmtab = htmtab & "<input type=""textbox"" style=""width:15%;"" id=""boxsearch"" NAME=""boxsearch"" size=""20"" value=""" & strsearch & """ onKeypress=""return event.keyCode!=13"">"
         htmtab = htmtab & "<input type=""button"" name=""Search"" value=""Search"">"
      end if
   end if

   if totrec>=maxoff and cc01<>0 then
'htmtab = htmtab & "<input type=""button"" name=""" & "but" & trim(cstr(yy+1)) & """ value=""" & "Select " & yy+1 & """"
'htmtab = htmtab &  " style=""background-color: #" & "cccccc" & "; color: #000000;""><br>"
      htmtab = htmtab & "<input type=""button"" name=""Precedent"" value=""Precedent"">"
      htmtab = htmtab & "<input type=""button"" name=""Next"" value=""Next"">"
      'ffra.WriteLn(" style=""background-color: #" & "cccccc" & "; color: #000000;"">")
   end if
   if ffranam="bot" and cc01<>0 then
      htmtab = htmtab & "Displaying " & offset + 1 & " to " & ymax + 1 & " / " & totrec + 1 & " Records"
      htmtab = htmtab & "<br><br>"
   end if

   '=== select buttons
   if cc01<>0 then
      '=== buttons var only if select is active
      if cc01<>0 then
         for yy=0 to ymax
         
         next
      end if
   end if
 
   fast=0
   '=== header
   if hh=1 then
      if logall = 1 then fil02.writeline "--- header frame"
   
      htmtab = htmtab & ttext & "<b><table width=""100%"" BORDERCOLOR=""black"" class=MsoTableGrid border=1 CELLSPACING=0 cellpadding=2 style='border-collapse:collapse;border:none'>"
      htmtab = htmtab & "<CAPTION></CAPTION><span style='color:purple'>" & vbcrlf
   
      if fast=1 then ffra.WriteLn(htmtab):htmtab=""
      '=== tableau html
      htmtab = htmtab & "<TR>"
      if fast=1 then ffra.WriteLn(htmtab):htmtab=""
      i=0
      For Each a In aaratit
         '=== columns names
         if cc01<>0 then if i=0 then htmtab = htmtab & "<td><p>Select</td>"
         '=== test to insert text box inside each field with a default value for editing
         test=0
         if test=0 then
            htmtab = htmtab & "<td><p>" & Trim(a) & "</td>"
            if fast=1 then ffra.WriteLn(htmtab):htmtab=""
         else
            '=== futur button to order by that column
            '=== futur textbox to search in this column
            htmtab = htmtab & "<td><p>" & Trim(a) & "</td>"
            if fast=1 then ffra.WriteLn(htmtab):htmtab=""
         end if
         i=i+1
         if dimnum=1 then exit for
      Next
         htmtab = htmtab & "</tr>"
         if fast=1 then ffra.WriteLn(htmtab):htmtab=""
   end if

   '=== middle
   if mm=1 then
      if logall = 1 then fil02.writeline "--- middle frame"
      '=== x is inversed when only one column
      if dimnum=1 then
         ymax=xmax
         '=== no offset possible here
         ymin=0
      else
         '=== there is 2 dimensions, that mean multiple row
         '=== so we must assume there is an offset
         ymin=offset
      end if
   
      For yy = ymin To ymax
         htmtab = htmtab & "<TR>"
         if dimnum=2 then
            'ffra.WriteLn(yy)
         
            '=== multiple row
            For xx = 0 To xmax
               'If IsNull(myarray(xx, yy)) Then myarray(xx, yy) = ""
               if xx=0 and cc01<>0 then
                  htmtab = htmtab & "<td><p>"
                  htmtab = htmtab & "<input type=""button"" name=""" & "but" & trim(cstr(yy+1)) & """ value=""" & "Select " & yy+1 & """"
                  htmtab = htmtab &  " style=""background-color: #" & "cccccc" & "; color: #000000;""><br>"
                  htmtab = htmtab & "</td>"
                  if fast=1 then ffra.WriteLn(htmtab):htmtab=""
               end if
             
            if ttxtbox=0 then
               htmtab = htmtab & "<td><p>" & aara(xx, yy) & "</td>"
               if fast=1 then ffra.WriteLn(htmtab):htmtab=""
            else
               'aa="<input type=""textbox"" style=""width:100%;"" id=""box" & xx & "_" & yy & """ NAME=""box" & xx & "_" & yy & """ size=""" & max(1,len(aara(xx, yy))) & """ value=""" & aara(xx, yy) & """ onKeypress=""return event.keyCode!=13"""
               ffra.WriteLn("<td><p><input type=""textbox"" style=""width:100%;"" id=""box" & xx & "_" & yy & """ NAME=""box" & xx & "_" & yy & """ size=""" & max(1,len(aara(xx, yy))) & """ value=""" & aara(xx, yy) & """ onKeypress=""return event.keyCode!=13""></td>")
               'htmtab = htmtab & "<td><p>" & aara(yy, xx) & "</td>"
               'if fast=1 then ffra.WriteLn(htmtab):htmtab=""
            end if
            Next
         else
         
            '=== there is only 1 row
            htmtab = htmtab & "<td><p>"
            htmtab = htmtab & "<input type=""button"" name=""" & "but" & trim(cstr(yy+1)) & """ value=""" & "Select " & yy+1 & """"
            htmtab = htmtab &  " style=""background-color: #" & "cccccc" & "; color: #000000;""><br>"
            htmtab = htmtab & "</td>"
         
            if ttxtbox=0 then
               htmtab = htmtab & "<td><p>" & aara(yy) & "</td>"
            else
               aa="<input type=""textbox"" style=""width:100%;"" id=""box" & yy & """ NAME=""box" & yy & """ size=""" & max(1,len(aara(yy))) & """ value=""" & aara(yy) & """ onKeypress=""return event.keyCode!=13"""
               htmtab = htmtab & "<td><p>" & aa & "</td>"
               'htmtab = htmtab & "<td><p>" & aara(yy, xx) & "</td>"
            end if
         
         end if
         htmtab = htmtab & "</tr>" & vbcrlf
         if fast=1 then ffra.WriteLn(htmtab):htmtab=""
 
      Next
   end if
   
   '=== footer
   if ff=1 then
      if logall = 1 then fil02.writeline "--- footer frame"
      htmtab = htmtab & "</table></span></b><br>"
      if logall=1 then fil02.writeline "--- writing data into frame"
      if fast=1 then ffra.WriteLn(htmtab):htmtab=""
   end if
 
   htmtab = htmtab & "</form>"
   if fast=1 then ffra.WriteLn(htmtab):htmtab=""
 
   aa = lcase(ffra.readystate)
   do until aa="complete" or aa="terminé" or aa="interactive"
      if logall = 1 then fil02.writeline "*********************************** readystate of " & ffranam & ": " & aa
      wscript.sleep 100
      aa = lcase(ffra.readystate)
   loop
   if fast=0 then ffra.WriteLn(htmtab)
   
   '=== reload (will not reload if we are in middle of a muliple elements/query table)
   if rr=1 then
      if logall=1 then
         'fil02.writeline htmtab
         fil02.writeline "--- reloading FRAME"
      end if
      'oie.document.getElementById("bottom").innerhtml htmtab
      'oie.document.getElementById("bottom").src
      'iframe.location.reload(true)
   
      aa = lcase(ffra.readystate)
      do until aa="complete" or aa="terminé" or aa="interactive"
         if logall = 1 then fil02.writeline "*********************************** readystate of " & ffranam & ": " & aa
         wscript.sleep 100
         aa = lcase(ffra.readystate)
      loop    
   
      ffra.location.reload(false)

   end if
 
   '=== ?
   if mm=1 and cc01<>0 then
      For yy = ymin To ymax
         if dimnum=2 then
            ffra.forms(0).elements("but" & trim(cstr(yy+1))).onclick = getref("button" & ffranam)
         else
         '=== there is only 1 column
            ffra.forms(0).elements("but" & trim(cstr(yy+1))).onclick = getref("button" & ffranam)
         end if
      Next
   end if
   if logall=1 then
      fil02.WriteLine date & " " & time & " max column: " & totrec
   end if
   if totrec>=maxoff and cc01<>0 then
      ffra.forms(0).elements("Precedent").onclick = getref("button" & ffranam)
      ffra.forms(0).elements("Next").onclick = getref("button" & ffranam)
   end if
   if ffranam="bot" and cc01<>0 then
      if secseatag<>0 then
         ffra.forms(0).elements("Search").onclick = getref("button" & ffranam)
      end if
   end if
   set ffra.onkeypress = GetRef("Check" & ffranam)
 
   'for i=0 to ubound(arabutnam)
   '   flef.forms(0).elements(arabutnam(i)).onclick = getref("buttonlef")
   'next
end function

sub oieready()
   do while oie.readystate<>4
      wscript.sleep 50
   loop
 
   'if logall=1 then fil02.writeline "============== oie readystate: " & oie.readystate
   'Do
   '   wscript.sleep 100
   'loop until oie.ReadyState = "Terminé" or oie.ReadyState = "Complete"
 
   Do While (oIE.Busy)
      wscript.sleep 50
   Loop
end sub


'=== ssea = search string

'=== tab 0 symptoms
'=== tab 1 components
'=== tab 2 diagnostics
'=== tab 3 causes

'=== ttyp 0 search
'=== ttyp 1 fast results
'=== ttyp 2 detail results

'=== ssufix = ordere by or something at the end of query
'                                            order  and   %
function makque(ssea, ttab, sselect,wwhere, ssufix,ooper,wwild)
   ssea = replace(ssea,"'","''")
   ssea = trim(ssea)
   sseaara = split(ssea," ") '=== array of all words for search
 
   ss = "select "
 
   ii = 0
   '=== columns to search in
   for each aa in allara(ttab,sselect)
      ss = ss & aa
      if ii<>ubound(allara(ttab,1),sselect) then ss = ss & ","
      ii=ii+1
   next
 
   '=== from table
   ss = ss & " from [" & alltab(ttab) & "] "
   if len(ssea)<>0 then
      ss = ss & "where ("
 
      '=== search word(S) in table, AND operator
      ii = 0
      for each ss2 in sseaara
         ii2=0
         for each aa in allara(ttab,wwhere)
            if wwild="" then
               ss = ss & "[" & aa & "] " & ooper & " " & wwild & ss2 & wwild
            else
               ss = ss & "[" & aa & "] " & ooper & " '" & wwild & ss2 & wwild & "'"
            end if
            if ii2 <> UBound(allara(ttab,wwhere), 1) then ss = ss & " or "
            ii2=ii2+1
         next
         if ii <> UBound(sseaara, 1) then ss = ss & ") and ("
         ii=ii+1
      next
      '=== order by a column name
      ss = ss & ")" & ssufix
   else
      ss = ss & ssufix
   end if
   makque = ss

end function

function exesql(objcon,tag,sql)
   
   on error resume next
   set tag = objcon.execute(SQL)
   if err<>0 then
      aaa= err.description
      on error goto 0
      l1 = "error in query"
      l2 = "query: " & sql
      l3 = "error: " & aaa
      l4 = "the program will now end"
      fbot.WriteLn(l1 & "<BR><br>" & l2 & "<BR><br>" & l3 & "<BR><br>" & l4 & "<BR><br>")
      'msgbox(l1 & vbcrlf & l2 & vbcrlf & l3 & vbcrlf & l4 & vbcrlf)
      if logall=1 then
          fil02.writeline "query:"
          fil02.writeline sql
          fil02.writeline err.description
       
      end if
      wscript.quit
   end if
   
end function

'=== tab = table object (adox)
'=== colnam = string containing column name

function crecol(tab,colnam)

Set objcol = CreateObject("ADOX.Column")

'typdat=202   '=== string adVarWChar
'maxlen=250
'typdat=131   '=== float adnumeric
'maxlen=10
typdat=3     '=== integer adinteger
maxlen=10

if typdat=3 then a="adinteger"
if typdat=202 then a="adVarWChar"
if typdat=131 then a="adnumeric"

objcol.name = colnam
objcol.type = typdat
if typdat = 3 or typdat = 202 then
objcol.DefinedSize = maxlen
if typdat=3 then
'=== must set parent catalog before setting autoincrement
Set objcol.ParentCatalog = objcat
objcol.Properties("AutoIncrement")=true
end if
elseif typdat = 131 then
objcol.precision = 28
objcol.numericscale = 8
end if
fbot.WriteLn("column creation: " & colnam & "<br>")
Tab.Columns.Append objcol

end function

'=== count the number of record in the array
function cnttotrec(aara)
 
   xmax = UBound(aara, 1) 'Returns the Number of columns  --- elements in first dimension
   on error resume next
   '=== chek the number of elements in second dimension, if there is none, then the array is only a list with 1 column
   ymax = UBound(aara, 2) 'Returns the Number of rows     --- elements in second dimension
 
   '=== number of dimensions in case there is only 1 column
   if err<>0 then
      aa = xmax
   else
      aa = ymax
   end if

   on error goto 0
 
   cnttotrec = aa

end function

function dynmidres(TTEXT,aara,rres,aaratit,ccoltot)
 
call oieready
htmtab=""
htmtab = htmtab & "<HTML><BODY>"
for each a in midara
htmtab = htmtab & a
next

htmtab = htmtab & TTEXT & ": " & rres & "<b><table  width=""100%"" BORDERCOLOR=""black"" class=MsoTableGrid border=1 CELLSPACING=0 cellpadding=2 style='border-collapse:collapse;border:none'>"
htmtab = htmtab & "<CAPTION></CAPTION><span style='color:purple'>"
htmtab = htmtab & "<TR>"

i=0
For Each aa In aaratit
'=== columns names
if i=0 then htmtab = htmtab & "<td><p>Choice</td>"
htmtab = htmtab & "<td><p>" & Trim(aa) & "</td>"
i=i+1
Next

htmtab = htmtab & "</tr>"

For xx = 0 To ccoltot
'If IsNull(myarray(xx, yy)) Then myarray(xx, yy) = ""
if xx=0 then
htmtab = htmtab & "<td><p>"
htmtab = htmtab & rres
htmtab = htmtab & "</td>"
end if

htmtab = htmtab & "<td><p>" & aara(xx,rres-1) & "</td>"
'col = col & myarray(xx, yy)
Next
htmtab = htmtab & "</tr>"
htmtab = htmtab & "</table></span></b><br>"

'=== image of the component
aa = """file://" & basedir & "PhotoHydComponent\002-00_HydroCraft_HC-EC_EndCover.jpg"""
aa = replace(aa,"\","/")
'<DIV style='display:none'><IMG SRC='image.gif'></DIV>
htmtab = htmtab & "<img src=" & aa & " alt=" & aa & " />"
htmtab = htmtab & "</BODY></HTML>"

oie.document.getElementById("middle").contentWindow.document.body.innerhtml = htmtab
'fmid.WriteLn(htmtab)

end function

FUNCTION SPLIT2(AA,SS)
             
   set bb= nothing
   BB = Split(AA, SS)
             
   set aa2=nothing
   AA2 = array("newsplittedarray")
   ii=0
   for each cc in bb
      if cc<>"" then
         redim PRESERVE aa2(ii)
         aa2(Ii)=cc
         ii=ii+1
      end if
   next

   split2 = aa2

END FUNCTION



function bigtablewait()
 
   strsearch=""
   offset=0
   do
      wscript.sleep 100
   
      '=== while we wait for input value (or button press), user can press "escape" key, "cancel" button or close internet explorer
      if resbutmidstr="cancel" or reskeymid=27 or bready=true or resbutlefstr<>"" then
         '=== if user pressed escape or cancel, we clear the frames
         if resbutmidstr="cancel" or reskeymid=27 then
            a = clefra(array("fmid","fbot"))
            resbutmidstr="cancel"
         end if
         exit do
      end if  
               
      if resbutbotstr="Precedent" then
         a=offset
         offset=offset-maxoff
         offset=max(0,offset)
         resbutbotstr=""
         if offset<>a then
            '=== totrec total number of record (displayed at end of first line)
            '=== maxoff maxiumm number of row in a page
            '=== offset page flip number (multiple of maxoff)
            a = dynbotcho(fbot, tabnam2, aratit, ara01, 1 ,1, 1, 1, 1, edtmod,"bot")
         end if
      end if            
   
      if resbutbotstr="Next" then
         a=offset
         offset=offset+maxoff
         if offset>totrec then offset=offset-maxoff
            resbutbotstr=""
            if offset<>a then
               a = dynbotcho(fbot, tabnam2, aratit, ara01, 1 ,1, 1, 1, 1, edtmod,"bot")
            end if
         end if
             
      if resbutbotstr="Search" or reskeybot=13 then
             
         strsearch=fbot.form01.boxsearch.Value
         strsearch=lcase(strsearch)
               
         '=== make a dynamic query to search for every words in every columns
         'makque(ssea, ttab, sselect,wwhere, ssufix,ooper,wwild)
         
         'if whe=3 then whe=0
         sql = makque(strsearch,tab,sel,whe,"",ooper,wwild)
         
         if logall=1 then
            fil02.WriteLine date & " " & time & " QUERY: "
            fil02.WriteLine sql
            'fil02.WriteLine date & " " & time & " Autoincrement status: " & objcol.Properties("AutoIncrement")
         end if
         a = exesql(objcon,tag,sql)
         
         if tag.eof=0 then
            myarray=TAG.GetRows()
         else
            redim myarray(coltot,0)
            'fbot.WriteLn("<br>total columns: " & coltot & "<br>")
            for i=0 to coltot
               myarray(i,0)="ERROR there was 0 record in this query"
            next
            fbot.WriteLn("<br>ERROR<br>" & sql & "<br><br>gave 0 results<br>")
         end if
               
         offset=0
         totrec = cnttotrec(myarray)
         if logall=1 then
            fil02.WriteLine date & " " & time & " total records: " & totrec+1
         end if
         a = dynbotcho(fbot, tabnam2, aratit, ara01, 1 ,1, 1, 1, 1, edtmod,"bot")
               
         resbutbotstr=""
      end if
      reskeybot=0
   
   loop while resbutbotstr=""
   offset=0
end function



function edit_xml_node(colNodes01,filename01)

'=== make a big table that will contain other tables inside
h = "<!DOCTYPE html>"
h = h & "<html>"

h = h & "<head>"
h = h & "<style>"
h = h & "table#items01 tr:nth-child(even) {"
h = h & "background-color: #eee;"
h = h & "}"
h = h & "</style>"
h = h & "</head>"

h = h & "<body>"
h = h & "<form name=form01>"
'=== box to focus (first editable data)
'h = h & "<BODY onLoad=""document.form01.facturation.focus()"">"

h = h & "<table width=""100%"" BORDERCOLOR=""black"" class=MsoTableGrid border=1 CELLSPACING=0 cellpadding=2 style='border-collapse:collapse;border: 1px solid black'>"

'h = h & "<script type=""text/javascript"">"
'h = h & "function message(nodename) {"
    'h = h & "var text = document.getElementById(nodename).value;"
    'h = h & "alert(text);"
    'h = h & "}"
'h = h & "</script>"

''''''''''''''''''''''''''''''''''''''''''''''''''''
' test indexed node access
''''''''''''''''''''''''''''''''''''''''''''''''''''
'colNodes01(0)(0)(0) = "test"

'Set objRecord = xmlDoc.createElement("billfrom")
'objRoot.appendChild objRecord
'objRecord.SetAttribute "displaynamefra", "Contracteur"

'Set objFieldValue = xmlDoc.createElement("compagny")
'objfieldvalue.SetAttribute "displaynamefra", "Compagnie"
'objFieldValue.Text = ""
'objRecord.appendChild objFieldValue

'Set xmlDoc = CreateObject("Microsoft.XMLDOM")

'xmlDoc.Async = "False"
'xmlDoc.Load(basedir & "\facturation" & numero01 & ".xml")

'Set colNodes=xmlDoc.selectNodes   ("/ITChecklist/ComputerAudit [ComputerName = 'atl-ws-100']")

'For Each objNode in colNodes
' xmlDoc.documentElement.removeChild(objNode)
'Next

'xmlDoc.Save basedir & "\facturation" & numero01 & ".xml"

'=== working
'Set colNodes02=xmlDoc.selectNodes("/facturation/billfrom/name")

'For Each objNode in colNodes02
' objnode.text = "serge fournier 555"
'Next

'txt = colnodes01(0).childNodes(0).childnodes(1).nodename
'fbot.WriteLn("<br>" & txt)

''''''''''''''''''''''''''''''''''''''''''''''''''''
' textbox creation to be able to edit xml nodes
''''''''''''''''''''''''''''''''''''''''''''''''''''
rootcnt01 = 0
prefix01 = "x" '=== textbox id need to start by a letter to defnie an event on it
prefix02 = "a" '=== this textbox ID is an attribute in xml, we treat it differently
For Each objNode01 in colNodes01
''''''''''''''''''''''''''''''''
' root name
''''''''''''''''''''''''''''''''
h = h & "<tr>" '=== line 1
text01 = objnode01.nodeName
h = h & "<td>"
h = h & "<input type=""textbox"" id=" & text01  & " NAME=""" & text01
h = h & """ size=""" & max(15,len(text01)) & """ value=""" & text01 & """ onKeypress=""return event.keyCode!=13"">"
h = h & "<input type=""button"" name=""add" & text01 & """ value=""&nbsp;+&nbsp;"">"
h = h & "</td>"
'h = h & "<td>" & objnode01.nodeName & "</td>"

childcnt01 = 0
for each objnode02 in objnode01.childnodes
'''''''''''''''''''''''''''''''''''''
' first child
'''''''''''''''''''''''''''''''''''''

h = h & "<tr>" '=== line 1
text01 = objnode02.nodename
h = h & "<td></td><td>"
h = h & "<input type=""textbox"" id=" & text01  & " NAME=""" & text01
h = h & """ size=""" & max(15,len(text01)) & """ value=""" & text01 & """ onKeypress=""return event.keyCode!=13"">"
h = h & "<input type=""button"" name=""add" & text01 & """ value=""&nbsp;+&nbsp;"">"
h = h & "</td>"
'h = h & "<td></td><td>" & objnode02.nodename & "</td>"

''''''''''''''''''''''''''''''''''''''''
' header (in bold)
''''''''''''''''''''''''''''''''''''''''
h = h & "<tr>"
h = h & "<td></td><td></td>"
h = h & "<td><b>Nodename</b></td>"
h = h & "<td><b>Node Text</b></td>"
'For Each objChild02 In objnode02.childNodes
' for each attribute01 in objchild02.attributes
h = h & "<td><b>Attribute Name</b></td>"
h = h & "<td><b>Attribute Text</b></td>"
' next
'next

h = h & "</tr>"

recordcnt01 = 0
For Each objChild02 In objnode02.childNodes
h = h & "<tr>"

''''''''''''''''''''''''''''''''''
' node name
''''''''''''''''''''''''''''''''''
h = h & "<td></td><td></td><td>" & objchild02.nodename  & "</td>"
'h = h & "<td>" & displaynamefra & "</td>"

''''''''''''''''''''''''''''''''''
' nodetext
''''''''''''''''''''''''''''''''''
'txt = colnodes01(0).childNodes(0).childnodes(1).nodename
'=== use exact rootnode/childnode/childnode number to put in the ID of the text box
'id01 = objnode02.nodename & "__" & objchild02.nodename

id01 = prefix01 & rootcnt01 & "_" & childcnt01 & "_" & recordcnt01

text01 = objchild02.text

h = h & "<td>"
'=== we add an X before the name, case a textbox without a name is BAD
h = h & "<input type=""textbox"" id=""" & id01 & """ NAME=""" & id01
'h = h & """ size=""" & max(15,len(text01)) & """ value=""" & text01 & """ onKeypress=""return event.keyCode!=13"" onblur=message(" & objchild02.nodename & ");>"

h = h & """ size=""" & max(15,len(text01)) & """ value=""" & text01 & """ onKeypress=""return event.keyCode!=13"");>"
'=== futur
'h = h & "<input type=""button"" name=""add" & text01 & """ value=""&nbsp;+&nbsp;"">"
h = h & "</td>"

'''''''''''''''''''''''''''''''''''
' node attributes
'''''''''''''''''''''''''''''''''''
attributescnt01 = 0
for each attribute01 in objchild02.attributes
'=== if there is more than one atribute, we go to the next line for the next one
if attributescnt01 > 0 then
'=== uncomment this for the attributes to display vertically
'h = h & "</tr><tr><td></td><td></td><td></td><td></td>"
end if
'displaynamefra = objchild02.getattribute("displaynamefra")

h = h & "<td>" & attribute01.name
h = h & "</td>"
text01 = attribute01.text
id01 = prefix02 & rootcnt01 & "_" & childcnt01 & "_" & recordcnt01 & "_" & attributescnt01

h = h & "<td>"
h = h & "<input type=""textbox"" id=""" & id01  & """ NAME=""" & id01
h = h & """ size=""" & max(15,len(text01)) & """ value=""" & text01 & """ onKeypress=""return event.keyCode!=13"">"

'h = h & "<input type=""button"" name=""add" & text01 & """ value=""&nbsp;+&nbsp;"">"
h = h & "</td>"

attributescnt01 = attributescnt01 + 1
next


'h = h & "<script type=""text/javascript"">"
'h = h & "document.getElementById(""" & objchild02.nodename & """).onblur=message(""" & objchild02.nodename & """);"
'h = H & "</script>"

'h = h & "<td>" & objchild02.text & "</td>"
'fbot.WriteLn("<td>" & displaynamefra & " " & objchild02.text)
'fmid.forms(0).elements(buttmp(ii)).onblur = getref("buttonmid")

'=== regenerate the event that call a sub if a button is pressed
'set fmid.onkeypress = GetRef("Checkmid")

h = h & "</tr>" '=== line 1
recordcnt01 = recordcnt01 + 1
next
h = h & "</tr>" '=== line 1
childcnt01 = childcnt01 + 1
next
rootcnt01 = rootcnt01 + 1
h = h & "</tr>" '=== line 1
next
h = h & "</form>"
h = h & "</body>"
h = h & "</html>"

fbot.WriteLn(h)
fbot.location.reload(true)

Do While (oIE.Busy)
  wscript.sleep 50
Loop

'=== wait till document loaded
do while oie.readystate<>4
  wscript.sleep 50
Loop

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' event creation for unblur (leaving/unselecting a textbox)
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
rootcnt01 = 0
For Each objNode01 in colNodes01
root01 = objnode01.nodeName '=== facturation
'=== any node under root
childcnt01 = 0
for each objnode02 in objnode01.childnodes
text01 = objnode02.nodename '=== bill
recordcnt01 = 0
For Each objChild02 In objnode02.childNodes
h = h & "<tr>"

'displaynamefra = objchild02.getattribute("displaynamefra")
'=== not editable
'text01 = displaynamefra
if instr(objnode02.nodename,"_")<>0 then
'fmid.WriteLn("<br>ERROR you cannot use underscore _ in name: " & objnode02.nodename )
end if

if instr(objchild02.nodename,"_")<>0 then
'fmid.WriteLn("<br>ERROR you cannot use undesrcore _ in name: " & objchild02.nodename)
end if

'name01 = objnode02.nodename & "__" & objchild02.nodename

id01 = prefix01 & rootcnt01 & "_" & childcnt01 & "_" & recordcnt01
'fmid.WriteLn("<br>Event defined on: " & id01 & " ---" & objnode02.nodename & " --- " & objChild02.nodename)
on error resume next

set fbot.form01.elements(id01).onblur = getref("onblurbot")
if err=0 then
'fmid.WriteLn("---" & name01)
else
fmid.WriteLn("<br>ERROR defining event onblur for: " & id01 & " id of the element might be defined twice in the same html form")
end if
on error goto 0

'=== attribute event
attributescnt01 = 0
for each attribute01 in objchild02.attributes
id01 = prefix02 & rootcnt01 & "_" & childcnt01 & "_" & recordcnt01 & "_" & attributescnt01

on error resume next

set fbot.form01.elements(id01).onblur = getref("onblurbot")
if err=0 then
'fmid.WriteLn("---" & name01)
else
fmid.WriteLn("<br>ERROR defining event onblur for: " & id01 & " id of the element might be defined twice in the same html form")
end if
on error goto 0

attributescnt01 = attributescnt01 + 1
next
recordcnt01 = recordcnt01 + 1
next
childcnt01 = childcnt01 + 1
next
rootcnt01 = rootcnt01 + 1
exit for '=== we use only one root for the moment
next
'fbot.body.onBlur = GetRef("onblurbot")

Do While (oIE.Busy)
  wscript.sleep 50
Loop

'=== wait till document loaded
do while oie.readystate<>4
  wscript.sleep 50
Loop

'set fbot.forms(0).datedue.onblur = getref("onblurbot")

'=== wait for any modification to occur
do

'=== flag to tell if the input is not valid
err01=0
'=== flag to say input is done, since there might be a defaut value, we must validate if user was finished
inpdon=0

'=== check if blur event occured (switch out of an input box)
'=== resblubotstr = name of the
'=== resblubotval = new value in the text box
'=== resblubotid = id (from html) for the textbox
if resblubotstr<>"" and bready=false and resbutlefstr="" and reskeymid<>27 and resbutmidstr<>"cancel" then

'=== User has clicked on another textbox
'fmid.WriteLn("<br>" & resblubotstr & " --- " & resblubotid & " --- " & resblubotval)

'=== find the xml node parent and children (record and text) using textbox id, split chain is __ (double underscore)
'=== contain root number, childnodes number, record number
'fmid.WriteLn("<br>" & colnodes01(idara01(0)).childNodes(idara01(1)).childnodes(idara01(2)).nodename)

if mid(resblubotstr,1,1) = "x" then

'=== record text modification
'fmid.WriteLn("<br>resblubotstr: " & resblubotstr)

'=== the id of the textbox is splitted to find the index for the xml element we want to update:
'=== node (facturation)
'=== first child (bill)
'=== record (name)

idara01 = split(right(resblubotid,len(resblubotid)-len(prefix01)), "_")

if colnodes01(idara01(0)).childNodes(idara01(1)).childnodes(idara01(2)).text <> resblubotval then
change01 = 1
colnodes01(idara01(0)).childNodes(idara01(1)).childnodes(idara01(2)).text = resblubotval
else
change01 = 0
end if

'fmid.WriteLn("<br>node unblur: " & colnodes01(idara01(0)).childNodes(idara01(1)).childnodes(idara01(2)).nodename & " Old text: " & colnodes01(idara01(0)).childNodes(idara01(1)).childnodes(idara01(2)).text)
'fmid.WriteLn("<br>node unblur: " & colnodes01(idara01(0)).childNodes(idara01(1)).childnodes(idara01(2)).nodename & " New text: " & resblubotval)

'=== something changed, we save

elseif mid(resblubotstr,1,1) = "a" then

'=== attribute modification

'=== the id of the textbox is splitted to find the index for the xml element we want to update:
'=== node (facturation)
'=== first child (bill)
'=== record (name)
'=== attribute (displaynamefra)

idara01 = split(right(resblubotid,len(resblubotid)-len(prefix02)), "_")

'for each ara01 in idara01
'fmid.WriteLn("<br>attribute"& ara01)
'next
'record01 = colnodes01(idara01(0)).childNodes(idara01(1)).childnodes(idara01(2)).text

'for each attribute01 in colnodes01(idara01(0)).childNodes(idara01(1)).childnodes(idara01(2)).attributes
' fmid.WriteLn("<br>attribute: "& attribute01.text)
'next
if colnodes01(idara01(0)).childNodes(idara01(1)).childnodes(idara01(2)).attributes(idara01(3)).text <> resblubotval then
change01 = 1
colnodes01(idara01(0)).childNodes(idara01(1)).childnodes(idara01(2)).attributes(idara01(3)).text = resblubotval
else
change01 = 0
end if

'fmid.WriteLn("<br>attribute modif: " & colnodes01(idara01(0)).childNodes(idara01(1)).childnodes(idara01(2)).attributes(idara01(3)).text)

end if

if change01 = 1 then
'=== filename may change to new invoice if we change the number
Set colNodes02 = xmlDoc.selectNodes("/" & colnodes01(idara01(0)).nodename & "/bill/id")

For Each objNode in colNodes02
numero01 = objnode.text '=== number of the invoice to change the filename before saving
Next

filename02 = basedir & "\facturation" & numero01 & ".xml"
xmlDoc.Save filename02

'=== what was modified in the xml tree
tree01 = "/" & colnodes01(idara01(0)).nodename
tree01 = tree01 & "/" & colnodes01(idara01(0)).childNodes(idara01(1)).nodename
tree01 = tree01 & "/" & colnodes01(idara01(0)).childNodes(idara01(1)).childnodes(idara01(2)).nodename
fmid.WriteLn("<br>node modified: " & tree01 & " --- xml doc saved")
end if

resblubotstr = ""
resblubotval = ""
resblubotid = ""

end if
'inpdon

wscript.sleep 50

if resbutmidstr="cancel" or reskeymid=27 or bready=true or resbutlefstr<>"" then
'=== if user pressed escape or cancel, we clear the frames
if resbutmidstr="cancel" or reskeymid=27 then
a = clefra(array("fmid","fbot"))
resbutmidstr="cancel"
end if
exit do
end if

loop while err01<>0 or inpdon=0
'fmid.WriteLn("<br>exiting edit")

end function


function validate(name110)
name110 = lcase(name110)
if name110 = "id" then name110 = "id"
'if instr(name110,"address")<>0 then name110 = replace(name110,"address","adres")
validate = name110
end function

Wednesday, October 28, 2015

offre de services au Saguenay

J'offre mes service au Saguenay comme administrateur réseau / programmeur. Je suis à mi-temps chez BlooBuzz comme administrateur réseau. J'y ai installé de nouvelles switch réseau, un serveur de base de données, configuré office 365 et automatisé l'installation et la configuration des postes. Donc si vous avez besoin d'un admin réseau senior qui fais de l'amélioration continue avec ses dons de programmeur, et que vous ne voulez pas payer du temps plein, je suis votre homme. Je ne refuserai pas du temps plein si vous avez besoin de plus.

https://ca.linkedin.com/pub/serge-fournier/32/235/15a

Derniers accomplissements:

Sharepoint ou office 365

PROBLÈME:
Vous n'aimez pas trop l'interface web de sharepoint?
Onedrive a atteint ses limites et ne cesse de faire des erreurs de synchronisation?

SOLUTION:
Il faut simplement configurer votre windows pour connecter des lettres de lecteurs en webdav et vos librairies sharepoint seront accessibles comme des lecteurs réseaux ordinaires.


PROBLÈME:
Formater et configurer vos ordinateurs est une longue tâche qui occupe complètement votre technicien informatique?

SOLUTION:
Une simple clef usb d'installation windows unattend, incluant votre windows, tous les correctifs microsoft (faits dans un ordre qui ne plante pas), les derniers codecs vidéos et quelques programmes (office, etc.). Le tout installé et configuré 4 fois plus rapidement que par un dvd.


PROBLÈME:
Vous rêves d'une base de données pour mieux gérer des datas de plus en plus volumineux? Microsoft SQL coûte trop cher?

SOLUTION:
MYSQL est gratuit et possède un connecteur odbc windows. Quelques scripts vbs ou vba, quelques requêtes de données excel et vous obtiendrez vos données dans le format que vous voulez.


PROBLÈME:
Vous n'avez pas de copies de sécurité? (backups)

SOLUTION:
Un script et votre base de données sera sauvegardée sur un disque portable à moindre coût. Un autre script et vos fichier le seront aussi. Le tout, par date, complet, incrémental et chaque jour. Et cela à une vitesse contrôlée pour ne pas ralentir votre travail.


PROBLÈME:
Vous avez perdu le contrôle de votre parc informatique? Tout le monde installe n'importe quoi?

SOLUTION:
Une base de donnée d'inventaire MYSQL. Un script pour inventorier tous les postes. Un rapport complet de tout ce qui est installé.


PROBLÈME:
Votre internet est toujours lent? Vous ne savez pas ce qui se passe?

SOLUTION:
Un simple port SPAN sur le port d'entrée internet (duplication du traffic du port) et un logiciel espion gratuit vous donnera le ip qui provoque le trafic et ralentit tout le monde. L'inventaire dans le base de donnée vous dira qui est loggué sur cet ordinateur.


PROBLÈME:
Votre parc informatique est infecté par un virus?

SOLUTION:
Un simple script exécuté avec les permissions administrateur, peut scanner tous les processus de tous les ordinateurs et éliminer le virus sans avoir à scanner tous les disque durs pendants des jours.


PROBLÈME:
Votre réseau est lent et vous ne savez pas pourquoi?

SOLUTION:
Est-ce que vos adaptateurs réseau sont bien configurés dans windows? Est-ce que vos pilotes sont à jour?


PROBLÈME:
Votre client ou fournisseur a besoin d'un fichier de 10 gig mais le courriel ne peut pas le prendre?

SOLUTION:
Un serveur de fichiers FTP internet sécuritaire est la solution. Trop compliqué? On lui attribue une lettre de lecteur localement et un simple copier coller rend le fichier disponible au client. Le tout protégé par un mot de passe, inclus dans le lien envoyé au client pour faciliter le téléchargement. Le client ou le fournisseur n'a qu'un click à faire.


PROBLÈME:
Vous avez besoin d'un outil rapide pour automatiser une tâche monotone et répétitive?

SOLUTION:
Les macros VBA ou un script VBS avec une interface WEB déjà programmée est la solution la plus rapide. Le langage script n'est pas compilé. Il est facile et rapide à modifier en cas d'ajout ou de modifications de la tâche. L'interface web est contrôlée par le script VBS, ce qui fait que vous n'avez pas besoin d'un serveur web. Elle est dynamique, s'élargit s'il y a plus de colonnes de données, s'allonge si il y a trop de lignes, et un simple copier coller peut transférer le résultat du travail n'importe où. Le résultat étant un tableau HTML. Il est aussi facile à imprimer aussi et s'adapte à la largeur de la page en long et en large lors de l'impression.







Tuesday, October 20, 2015

google safesearch

Hi,

My goolge safe search was stuck lately

Many solutions were tried, and it turned out the working one was to verify the DNS setting on my network card protocol ipv4

I tried a few hacks recently, infected my computer, cleaned it, but the DNS setting was a left over from these infections.

Restoring the DNS to "automatic" did the trick

Now i can turn safesearch off



Sunday, August 9, 2015

mysql php login and password authentication

Hello,

2016-03-07 Noticed that is the page reload, the session variables are reset. I must initiate session on page reload. Code will change soon to include a basic code inside main loop.

2015-08-09 completly changed the mysql database and data creation to use a function and dynamic arrays


My last post about login and password in PHP was really short

So i added some MYSQL

Mysql is a database engine
In this program we will initialise variables at the start (before login)
Then we will create a database (siteweb01) if it does not exist
Then we will create a table (users01) if it does not exist
Then we will create columns (fields) for this table

Important: the column name will all have the same name as the arrays that contain the logins, passwords, and fullname (and securitylevel)

One column will be "id" wich name will never change, is a primary key, and is autoincrement
We never update the field "id"
An "id" field is mandatory for a table (in theory)

One column will become a primary key column, and will contain the loginname (we do not want the same loginname for 2 persons)

I also added a session variable just in case someone refresh the page. This will prevent the login from being posted twice for no reason.

Be aware that some browsers remember logins and passwords and switch password automatically if there is more than one in memory and if a password fail.

Also, the array containing the loginnames etc. is accessed using dynamic code
(dynamic code = executing some php code inside a variable with eval)
This is because i did not want my array to be only 2 dimensionnals array with numbers
First dimension would have been the users (1 dimension for each user)
Second dimension would have been: loginname, fullname, password etc. (0, 1, 2 etc.)
I did not want "fullname" to be array dimension 0
I wanted my array to have nice names

Debugmode can be put to 0 if you dont want all the trash text in the web page

This code is meant as a model, so error trapping is everywhere.

Requirements:
So the requirement for this is still WAMP, wich include a apache web server and mysql service

If your wamp icon is yellow, only the web part may be active, not the mysql service
You must install and activate the mysql service (in the wamp icon menu)

Create this file with notepad.exe
Save this in c:\wamp\www

---------------------- index.php ---------------------------------
<!DOCTYPE html>

<html:html>
<html:body>

<html>
<head>

<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /><div>

<title>Login and password in PHP</title>

</head>

<body>

<?php
// debug mode is ON, lots of echo will display message about working order of the page
$debugmode = 1;
session_start();


header("Cache-Control: private, max-age=10800, pre-check=10800");

if(!isset($_COOKIE["PHPSESSID"]))
{
// first load of page
// initialize session variables
$_SESSION['loginok'] = 0;
$_SESSION['securitylevel'] = 0;
$_SESSION['username'] = "";
$_SESSION['fullname'] = "Guest";
$_SESSION['logindone'] = 0;

if($debugmode==1) {echo "SESSION variables initialized<br>";};

// second load of page or more
if($debugmode==1) {echo "Not first load, no global variables initializing<br>";};
//if($debugmode==1) {echo "Session logindone: " . $_SESSION['logindone']."<br>";};
};

if(!isset($userstot))
{
// initialize program variables (in this sub, not public to functions or sub, not shared to any other program
if($debugmode==1) {echo "Variables initialized<br>";};

// mysql database
$mysqldbname = "siteweb01";
// mysql users table

$mysqltablename = "users01";

// used to read user and authenticate
$mysqluserstable = "users01";

// mysql fields to create in table
// struct equivalent to be able to pass one array as parameter to create the sql table with the data
$i = 0;
$mysqlfields[$i]['fieldname'] = "username";
$mysqlfields[$i]['type'] = "VARCHAR(50)";
$mysqlfields[$i]['primarykey'] = 1; // 1 = this will be a primary key column, 0 = not
$mysqlfields[$i]['autoincrement'] = 0;
$i++;
$mysqlfields[$i]['fieldname'] = "password";
$mysqlfields[$i]['type'] = "VARCHAR(50)";
$mysqlfields[$i]['primarykey'] = 0; // 1 = this will be a primary key column, 0 = not
$mysqlfields[$i]['autoincrement'] = 0;
$i++;
$mysqlfields[$i]['fieldname'] = "fullname";
$mysqlfields[$i]['type'] = "VARCHAR(255)";
$mysqlfields[$i]['primarykey'] = 0; // 1 = this will be a primary key column, 0 = not
$mysqlfields[$i]['autoincrement'] = 0;
$i++;
$mysqlfields[$i]['fieldname'] = "securitylevel";
$mysqlfields[$i]['type'] = "VARCHAR(50)";
$mysqlfields[$i]['primarykey'] = 0; // 1 = this will be a primary key column, 0 = not
$mysqlfields[$i]['autoincrement'] = 0;
$i++;
$mysqlfields[$i]['fieldname'] = "id"; // there must ALWAYS be an ID column (primary key automatically, name in lowercase)
$mysqlfields[$i]['type'] = ""; // type does not matter as this is altered to be a primary key
$mysqlfields[$i]['primarykey'] = 1; // 1 = this will be a primary key column, 0 = not
$mysqlfields[$i]['autoincrement'] = 1; // a id column is always autoincrement

// struct
$i = 0;
$mysqldatas[$i]['username'] = "admin";
$mysqldatas[$i]['password'] = "admin";
$mysqldatas[$i]['fullname'] = "Serge Fournier";
$mysqldatas[$i]['securitylevel'] = 100;
$i++;
$mysqldatas[$i]['username'] = "admin2";
$mysqldatas[$i]['password'] = "admin2";
$mysqldatas[$i]['fullname'] = "Serge Fournier 2";
$mysqldatas[$i]['securitylevel'] = 50;

$userstot = count($mysqldatas); // total users would be 2

// create a mysql database with the login array

// connect to mysql server locally @ = no php error if it fail
$con01 = @mysqli_connect("localhost","root","","");
if(mysqli_connect_error()==null)
{
// call mysql db, table, field creation and insertion or update if primary key exist
$dummy = makemysql($con01, $mysqldbname, $mysqltablename, $mysqlfields, $mysqldatas);
}
else
{
echo "ERROR mysqli_connect: " . mysqli_connect_error()."<br>";
unset($con01);
};

// end of creation of database, creation of table, creation of columns(fields), insertion/update of all line from an array for users table

// now, this mysql table was initially from an array
// but now we will be able, later, to add users from the web page itself in the mysql database (new inscriptions)

$errorlogin = "";

}

if(isset($_POST['submitlogin']) and $_SESSION['logindone'] == 0)
{
//if(empty($_POST['username'])){$_SESSION['loginok'] = 0;};
//if(empty($_POST['password'])){$_SESSION['loginok'] = 0;};


$usernameresult = trim($_POST['username']);
$passwordresult = trim($_POST['password']);
$usercnt = 0;
if($debugmode==1) {echo "Total number of users: $userstot <br>";};

// MYSQL validation of login and password (in database we created with the array before we got here)
if(isset($con01))
{
if (mysqli_select_db($con01, $mysqldbname))
{
if ($result01 = mysqli_query($con01,"SELECT * FROM $mysqluserstable"))
{
// connect, db, and query are ok
while ($row = $result01->fetch_array())
{
// list all login and passwords in the sql database
// echo '<br>line: '.$row["username"].' '.$row["password"].' '.$row["securitylevel"].'<br>';
if($usernameresult == $row["username"])
{
if($debugmode==1) {echo "Username valid, cheking password...<br>";};
if($passwordresult == $row["password"])
{
$_SESSION['loginok'] = 1;
$_SESSION['fullname'] = $row["fullname"];
$_SESSION['username'] = $row["username"];
$_SESSION['securitylevel'] = $row["securitylevel"];
// if($debugmode==1) {echo "session value (1 is login and password ok, 0 is bad something): " . $_SESSION['loginok']."<br>";};
$_SESSION['logindone'] = 1;
if($debugmode==1) {echo "Session logindone: " . $_SESSION['logindone']." Session loginok: ".$_SESSION['loginok']."<br>";};
};
}; //if($usernameresult == $row["username"])
}; // while

mysqli_free_result($result01);
}
else
{
// query sucess
echo "ERROR mysql query returned an error<br>";
echo("ERROR mysqli_query: ".mysqli_errno($con01)." ".mysqli_error($con01)."<br>");
}; //mysqli_query
}
else
{
echo "ERROR mysql database selection did not work<br>";
echo("ERROR mysqli_select_db: " . mysqli_errno($con01)." ".mysqli_error($con01)."<br>");
}; // mysqli_select_db

}
else
{
echo "ERROR mysql connection does not exist: con01<br>";
}; // mysqli_connect

/* // array validation of login and password
foreach($username as $usernameloop)
{
if($usernameresult == $usernameloop)
{
if($debugmode==1) {echo "Username valid, cheking password...<br>";};
if($passwordresult == $password[$usercnt])
{
$_SESSION['loginok'] = 1;
$_SESSION['fullname'] = $fullname[$usercnt];
$_SESSION['username'] = $username[$usercnt];
$_SESSION['securitylevel'] = $securitylevel[$usercnt];
if($debugmode==1) {echo "session value (1 is login and password ok, 0 is bad something): " . $_SESSION['loginok']."<br>";};
$_SESSION['logindone'] = 1;
if($debugmode==1) {echo "Session logindone (submitlogin): " . $_SESSION['logindone']."<br>";};
};
};
$usercnt = $usercnt + 1;
};
*/
// is login and password ok? if not set an error message for next page reload
if($_SESSION['loginok'] == 1)
{
$errorlogin = "";
}
else
{
$errorlogin = "ERROR Wrong login or password. This is case sensitive. Chek your caps lock state";
};
};

if(isset($_POST['submitlogoff']))
{
$_SESSION['loginok'] = 0;
$_SESSION['logindone'] = 0;

// close mysql connection
if(isset($con01))
{
mysqli_close($con01);
unset($con01);
};

if($debugmode==1) {echo "Session logindone (submitlogoff): " . $_SESSION['logindone']."<br>";};
};

if($_SESSION['loginok'] == 1)
    {
    // second load of page (this is a view refresh)


// main program ///////////////////////////////////////////////

echo "<h1>Main program</h1><br>";

echo "<br>Welcome ".$_SESSION['fullname']."<br>";
echo "<br>Your username is: ".$_SESSION['username']."<br>";
echo "<br>Your security level is: ".$_SESSION['securitylevel']."<br>";

// mysql connexion (for verification of list of users and password)
if(isset($con01))
{
if (mysqli_select_db($con01, $mysqldbname))
{

// the row will be in an array
// we will build query dynamically with all rows
// so we can use the same array to write to database


if ($result01 = mysqli_query($con01,"SELECT * FROM $mysqluserstable"))
{
// connect, db, and query are ok
while ($row = $result01->fetch_array())
{
// list all login and passwords in the sql database

// activate if you want to verify something
// echo '<br>line: '.$row["username"].' '.$row["password"].' '.$row["securitylevel"].'<br>';
};
mysqli_free_result($result01);
}
else
{
// query sucess
echo "ERROR mysql query returned an error<br>";
echo("ERROR mysqli_query: " . mysqli_errno($con01));
}; //mysqli_query
}
else
{
echo "ERROR mysql database selection did not work<br>";
echo("ERROR mysqli_select_db: " . mysqli_errno($con01)."<br>");
}; // mysqli_select_db

}
else
{
echo "ERROR mysql connection does not exist: con01<br>";
}; // mysqli_connect

// logoff button
$html = "";
$html.="<br><form id='logoff' action='{$_SERVER['PHP_SELF']}' method='post' accept-charset='UTF-8'>";
$html.="<fieldset>";
$html.="<legend>Logoff</legend>";
$html.="<input type='submit' name='submitlogoff' value='Logoff' />";
$html.="</fieldset>";
$html.="</form>";

echo $html;
ob_flush(); // empty any web browser buffer so text display immediatly
flush();
 
    }
else
{
// login form, username and password box
if($debugmode==1) {echo "Session loginok value: " . $_SESSION['loginok'] . " (0 = you are not logged in)<br>";};

$html="<form id='login' action='{$_SERVER['PHP_SELF']}' method='post' accept-charset='UTF-8'>";
$html.="<fieldset>";
$html.="<legend>Login</legend>";
$html.="<label for='username' >UserName*:</label>";
$html.="<input type='text' name='username' id='username'  maxlength='50' />";
$html.="<label for='password' >Password*:</label>";
$html.="<input type='password' name='password' id='password' maxlength='50' />";
$html.="<input type='submit' name='submitlogin' value='Login' /> $errorlogin";
$html.="</fieldset>";
$html.="</form>";

echo $html;
ob_flush(); // empty any web browser buffer so text display immediatly
flush();
};

///////////////////////////////////////////////////////////////////////////////////

function makemysql($con01, $mysqldbname, $mysqltablename, $mysqlfields, $mysqldatas)
{
// this function will create a mysqldatabase and upinsert data in it
// insert if data do not exist
// update if data primary key exist (there must be a primary key field, like "username"

// reference
// $mysqlfields[$i]['fieldname'] = "fullname";
// $mysqlfields[$i]['type'] = "VARCHAR(255)";
// $mysqlfields[$i]['primarykey'] = 0; // 1 = this will be a primary key column, 0 = not
// $mysqlfields[$i]['autoincrement'] = 0;

global $debugmode;

if($debugmode==1) {echo "<br>Function to create mysql database, table, fields, upinsert data<br>";};

// does database exist?
if (!mysqli_select_db($con01, $mysqldbname))
{
echo("Creating database: $mysqldbname<br>");
$query = "CREATE DATABASE $mysqldbname";
mysqli_query($con01,$query);
$query = "ALTER DATABASE `$mysqldbname` CHARACTER SET utf8 COLLATE utf8_general_ci";
mysqli_query($con01,$query);
}
else
{
// database already exist
if($debugmode==1) {echo "MYSQL database $mysqldbname already exist<br>";};
};

// selecting database
if (mysqli_select_db($con01, $mysqldbname))
{
// database exist

// checking if table exist
$query ="SELECT * FROM $mysqltablename limit 1";
if (!$result01 = mysqli_query($con01, $query))
{
if($debugmode==1) {echo "ERROR mysql table does not exist or no answer: $query<br>";};
// creating table
$query = "CREATE TABLE `$mysqldbname`.`$mysqltablename`( `".$mysqlfields[0]['fieldname']."` ".$mysqlfields[0]['type'].")";
if($debugmode==1) {echo "MYSQL creating table: $query<br>";};
$result01 = mysqli_query($con01,$query);
}
else
{
if($debugmode==1) {echo "MYSQL Table responded: $query<br>";};
};
$query ="SELECT * FROM $mysqltablename limit 1";
if ($result01 = mysqli_query($con01,$query))
{
$columnscnt = 0;
foreach($mysqlfields as $mysqlfield)
{
//$columnname = $mysqlfield['fieldname'];

if (!$result01 = mysqli_query($con01,"SELECT ".$mysqlfield['fieldname']." FROM $mysqltablename limit 1"))
{
if($debugmode==1) {echo "MYSQL Column does not exist: ".$mysqlfield['fieldname']."<br>";};
// creating column
$query = "ALTER TABLE `$mysqldbname`.`$mysqltablename` ADD COLUMN `".$mysqlfield['fieldname']."` ".$mysqlfield['type'];
// NULL AFTER 'fullname'"

// ID
if($mysqlfield['fieldname'] == "id")
{
$query = "ALTER TABLE `$mysqldbname`.`$mysqltablename` ADD COLUMN `id` INT NULL AUTO_INCREMENT, ADD KEY(`id`);";
};

if (!$result01 = mysqli_query($con01,$query))
{
echo "ERROR mysql altering table, inserting column: ".$mysqlfield['fieldname']."<br>";
echo "ERROR mysql altering table, inserting column: $query<br>";
}
else
{
if($debugmode==1) {echo "MYSQL Column created: $query<br>";};
};
}
else
{
if($debugmode==1) {echo "MYSQL Column ok: ".$mysqlfield['fieldname']."<br>";};
};
$columnscnt = $columnscnt + 1;
};

// add primary key for some columns
$columnscnt = 0;
foreach($mysqlfields as $mysqlfield)
{
//if($debugmode==1) {echo ($mysqlprimarykey[$columnscnt] == 1 and $columnname !== "id")."<br>";};

// add primary key if this column require it. NOTE: if this is added after column wa created, it wont execute because column already exist
if($mysqlfield['primarykey'] == 1 and $mysqlfield['fieldname'] !== "id") // Id column is exempted as it is created as non null autoincrement already
{
$query = "ALTER TABLE `$mysqldbname`.`$mysqltablename` CHANGE `".$mysqlfield['fieldname']."` `".$mysqlfield['fieldname']."` ".$mysqlfield['type']." ";
$query.="CHARSET utf8 COLLATE utf8_general_ci NOT NULL, ADD PRIMARY KEY (`".$mysqlfield['fieldname']."`);";
if (!$result01 = mysqli_query($con01,$query))
{
if($debugmode==1) {echo "ERROR MYSQL column defined as primary key: $query<br>";};
if($debugmode==1) {echo "ERROR ".mysqli_errno($con01)." ".mysqli_error($con01)."<br>";};
// Multiple primary key defined (when we redo the same primary key)
}
else
{
if($debugmode==1) {echo "MYSQL column defined as primary key: ".$mysqlfield['fieldname']."<br>";};
};
};
$columnscnt = $columnscnt + 1;
};

// verification if creation of a column worked
$columnscnt = 0;
$fatalerror = 0;
foreach($mysqlfields as $mysqlfield)
{
if (!$result01 = mysqli_query($con01,"SELECT ".$mysqlfield['fieldname']." FROM $mysqltablename limit 1"))
{
if($debugmode==1) {echo "ERROR MYSQL Column does not exist after we tried to create it: ".$mysqlfield['fieldname']."<br>";};
$fatalerror = $fatalerror + 1;
};
$columnscnt = $columnscnt + 1;
}


if($fatalerror == 0)
{
if($debugmode==1) {echo "MYSQL Column existence verified. missing: $fatalerror<br>";};
// all columns exist (we did not check their type tough)
if($debugmode==1) {echo "MYSQL all columns ok, database ok, table ok<br>";};

///////////////////////////////////////////////////////////
// insert stuff (array) in database/table if it does not exist (merge or upinsert)
///////////////////////////////////////////////////////////



// upinsert all elements from array in the database
$line = 0;
foreach($mysqldatas as $mysqldata)
{
$querypart1 ="insert into `$mysqltablename` (";
$querypart2 =") values (";
$querypart3 =") ON DUPLICATE KEY UPDATE ";

$columnscnt = 0;
$columnmax = count($mysqlfields);

if($debugmode==1) {echo "Inserting a line with ".$columnmax." columns. Line: ".$line."<br>";};

foreach($mysqlfields as $mysqlfield)
{
// DO NOT INCLUDE ID IN a merge (also called upinsert or insert on duplicate key update in mysql)
if ($mysqlfield['fieldname']!= "id")
{
$querypart1.="`".$mysqlfield['fieldname']."`";

// instead of having only number array
// i use eval to get the name of the array that contain each column value we want
// the name of the column in mysql is the same name as the array that contain the value we want

// test string (to see what i do with all the \ to be able to use " inside the eval
$test="";
//$test = "\$querypart2.=$mysqldata[$mysqlfield['fieldname']];
//if($debugmode==1) {echo($columnscnt." ".$test."<br>");};
//if($debugmode==1) {echo("data: ".$mysqldata[$mysqlfield['fieldname']]."<br>");};

// dynamic code. all this code is replaced by the eval
//if($columnscnt==0) {$querypart2.="'".$username[$line]."'";};
//if($columnscnt==1) {$querypart2.="'".$password[$line]."'";};
//if($columnscnt==2) {$querypart2.="'".$fullname[$line]."'";};
//if($columnscnt==3) {$querypart2.=$securitylevel[$line];};
//eval("\$querypart2.=\"'\".$".$columnname."[\$line].\"'\";");
$querypart2.="'".$mysqldata[$mysqlfield['fieldname']]."'";

// the value mysql need when the insert become an update
// when the line we want to insert have a primary key identical to what we try to insert
// in this case, username is defined as a primary key in mysql when we create the column in precedent lines
$querypart3.=$mysqlfield['fieldname']."=values(".$mysqlfield['fieldname'].")";

// id=LAST_INSERT_ID(id)

if($columnscnt!=$columnmax-1)
{
if($mysqlfields[$columnscnt + 1]['fieldname'] != "id")
{
$querypart1.=",";
$querypart2.=",";
$querypart3.=",";
};
};
}; // ($columnname != "id")
$columnscnt = $columnscnt + 1;
}; // for each columnname
if($debugmode==1) {echo "MYSQL insert on duplicate key update: ".$querypart1.$querypart2.$querypart3."<br>";};
// ON DUPLICATE UPDATE b = VALUES(b), c = VALUES(c)

$query = $querypart1.$querypart2.$querypart3;
//"INSERT INTO `$mysqldbname`.`$mysqltablename` (`username`, `password`, `securitylevel`, `fullname`) VALUES ('admin', 'admin', '100', 'Serge Fournier');";
if ($result01 = mysqli_query($con01,$query))
{
if($debugmode==1) {echo "MYSQL insert on duplicate key update success<br>";};
}
else
{
if($debugmode==1) {echo "ERROR MYSQL insert on duplicate key update<br>";};
};
$line++;
}; // for $line
}
else
{
echo "ERROR mysql $fatalerror column is missing after we tried to create all columns, at verification of it's existence<br>";

}; // if fatalerror
}
else
{
echo "ERROR mysql table does not exist after we tried to create it: $mysqltablename<br>";
}; //if ($result01 = mysqli_query($con01,$query))

}
else
{

echo "ERROR mysql we tried to create database<br>";
echo "ERROR mysql after trying to create database, mysqli_select_db did not work<br>";
echo("ERROR mysqli_select_db: " . mysqli_errno($con01)."<br>");
}; //if (mysqli_select_db($con01, $mysqldbname))
if($debugmode==1) {echo "<br>";};
};

?>

</html>
</body>
</html:body>
</html:html>

Saturday, August 1, 2015

php login and password authentication

Hello,
2015-08-08 changed the detection of view for a session detection with a cookie (default name of a php session)


A friend asked me to add a login and password to his php web site
I checked internet, I did not find a nice example (well, not quickly)

Security concern:
This type of login and password is half secure (if someone hack your root, he will get all login and passwords!!!)

Requirement package:
wampserver2.5-Apache-2.4.9-Mysql-5.6.17-php5.5.12-64b.exe

Requirement procedure:

To start a php web site locally, port 80 must be free, close skype or set his additionnals call option off on on another port

Install php WAMP

Copy index.php in c:\wamp\www

Type localhost in adress bar of any browser to access your local site (this will pick index.php as the first php web page)

----------------- index.php ----- use notepad.exe or notepad2.exe ------------------

<!DOCTYPE html>

<html:html>
<html:body>

<html>
<head>

<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /><div>

<title>Login and password in PHP</title>

</head>

<body>

<?php
// debug mode is ON, lost of echo will display message about working order of the page
$debugmode = 1;
session_start();

// initialize global variables on first load of page
// view indicate a refresh if it set, but ! mean it is not set
if(!isset($_COOKIE["PHPSESSID"]))
{
// first load of page
// initialize session variables
$_SESSION['loginok'] = 0;
$_SESSION['securitylevel'] = 0;
$_SESSION['username'] = "";
$_SESSION['fullname'] = "Guest";

if($debugmode==1) {echo "globals SESSION variables initialized";};
}
else
{
// second load of page or more
if($debugmode==1) {echo "Not first load, no global variables initializing<br>";};
};

if(!isset($userstot))
{
// initialize program variables (in this sub, not public to functions or sub, not shared to any other program
if($debugmode==1) {echo "Globals regular variables initialized<br>";};
$i = 0;
$username[$i]="admin";
$password[$i]="admin";
$fullname[$i]="Serge Fournier";
$securitylevel[$i] = "100";

$i++;
$username[$i]="admin2";
$password[$i]="admin2";
$fullname[$i]="Serge Fournier 2";
$securitylevel[$i] = "10";

$userstot = count($username); // total users would be 2

$errorlogin = "";
}

if(isset($_POST['submitlogin']))
{
//if(empty($_POST['username'])){$_SESSION['loginok'] = 0;};
//if(empty($_POST['password'])){$_SESSION['loginok'] = 0;};
$usernameresult = trim($_POST['username']);
$passwordresult = trim($_POST['password']);
$usercnt = 0;
if($debugmode==1) {echo "Total number of users: $userstot <br>";};
foreach($username as $usernameloop)
{
if($usernameresult == $usernameloop)
{
if($debugmode==1) {echo "Username valid, cheking password...<br>";};
if($passwordresult == $password[$usercnt])
{
$_SESSION['loginok'] = 1;
$_SESSION['fullname'] = $fullname[$usercnt];
$_SESSION['username'] = $username[$usercnt];
$_SESSION['securitylevel'] = $securitylevel[$usercnt];
if($debugmode==1) {echo "session value (1 is login and password ok, 0 is bad something): " . $_SESSION['loginok']."<br>";};

};
};
$usercnt = $usercnt + 1;
};
if($_SESSION['loginok'] == 1)
{
$errorlogin = "";
}
else
{
$errorlogin = "ERROR Wrong login or password. This is case sensitive. Chek your caps lock state";
};
};

if(isset($_POST['submitlogoff']))
{
$_SESSION['loginok'] = 0;
};

if($_SESSION['loginok'] == 1)
    {
    // second load of page (this is a view refresh)


// main program ///////////////////////////////////////////////

echo "<h1>Main program</h1><br>";

echo "<br>Welcome ".$_SESSION['fullname']."<br>";
echo "<br>Your username is: ".$_SESSION['username']."<br>";
echo "<br>Your security level is: ".$_SESSION['securitylevel']."<br>";



// logoff button
$html = "";
$html.="<br><form id='logoff' action='{$_SERVER['PHP_SELF']}' method='post' accept-charset='UTF-8'>";
$html.="<fieldset>";
$html.="<legend>Logoff</legend>";
$html.="<input type='submit' name='submitlogoff' value='Logoff' />";
$html.="</fieldset>";
$html.="</form>";

echo $html;
ob_flush(); // empty any web browser buffer so text display immediatly
flush();
 
    }
else
{
// login form, username and password box
if($debugmode==1) {echo "Session loginok value: " . $_SESSION['loginok'] . " (0 = you are not logged in)<br>";};

$html="<form id='login' action='{$_SERVER['PHP_SELF']}' method='post' accept-charset='UTF-8'>";
$html.="<fieldset>";
$html.="<legend>Login</legend>";
$html.="<label for='username' >UserName*:</label>";
$html.="<input type='text' name='username' id='username'  maxlength='50' />";
$html.="<label for='password' >Password*:</label>";
$html.="<input type='password' name='password' id='password' maxlength='50' />";
$html.="<input type='submit' name='submitlogin' value='Login' /> $errorlogin";
$html.="</fieldset>";
$html.="</form>";

echo $html;
ob_flush(); // empty any web browser buffer so text display immediatly
flush();
};
?>

</html>
</body>
</html:body>
</html:html>