Free Visual Basic / in VB / in SQL / MS Access Computer Programming Code Examples I of II ( Learn / Do )
Visual Basic / VB / SQL / MS Access Code Examples: Intro
Groups I and II are debugged code fragments from business applications that I have written over the years. You will find standalone blocks of SQL, record set processing, data manipulation (field and character level), and some useful GUI routines. This page is Code Group I.
To scroll left/right you can:
Use the scroll bar at the end of each module.
Or
Click anywhere on the code and use the left/right arrows.
(If the scroll bar isn’t visible and the code text isn’t sequentially numbered at left, then your computer may have run low on memory and is not displaying this page correctly. For a PC tune-up check list, you can click here (new window).)
Visual Basic / VB / SQL / Access Code Examples
'TO RUN WORD OR ANY OTHER SOFTWARE FROM WITHIN A VISUAL BASIC APPLICATION.
Private Sub cmdDocumentation_Click()
Dim RetVal
RetVal = Shell("C:\Program Files\Microsoft Office\Office\WINWORD.EXE XYZ.DOC", 1)
End Sub
Private Sub cmdDBpicture_Click()
frmDBpicture.Show 1
End Sub
Private Sub cmdTechDoc_Click()
Dim RetVal
RetVal = Shell("C:\Program Files\Microsoft Office\Office\WINWORD.EXE XYZtech.DOC", 1)
End Sub
Private Sub cmdUserDoc_Click()
Dim RetVal
RetVal = Shell("C:\Program Files\Microsoft Office\Office\WINWORD.EXE XYZuser.DOC", 1)
End SubVisual Basic / VB / SQL / Access Code Examples
'OBTAINING USER DATE RANGE and
'DATE MANIPULATION CODE
'frmDATERANGE screen
'Notes:
' Variables declared as public in Module1
' Public procedures can be found in Module1
Private Sub Form_Load()
varSTARTDATE = Format(Date, "mm/01/yy")
varENDDATE = DateAdd("d", -1, DateAdd("m", 1, varSTARTDATE))
txtSTARTDATE.Text = varSTARTDATE
txtENDDATE.Text = varENDDATE
End Sub
Private Sub cmdMONTH_Click(Index As Integer)
varSTARTDATE = CDate(Trim(Str(Index)) + "/01/" + Format(Date, "yy"))
varENDDATE = CDate(DateAdd("d", -1, DateAdd("m", 1, varSTARTDATE)))
txtSTARTDATE.Text = varSTARTDATE 'global
txtENDDATE.Text = varENDDATE 'global
End Sub
Private Sub cmdProceed_Click()
varDR = True
varSTARTDATE = CStr(txtSTARTDATE.Text)
varENDDATE = CStr(txtENDDATE.Text)
varPROCEED = True
varCANCEL = False
Me.Hide
End Sub
Private Sub cmdCancel_Click()
varDR = False
varPROCEED = False
varCANCEL = True
Unload Me
End SubVisual Basic / VB / SQL / Access Code Examples
Private Sub cmdPrintReport_Click()
'CREATE DATA AND PRINT REPORT USING A SPECIFIED DATE RANGE
Dim dbs As Database
Dim strSQL As String
Dim TheSelectedMonth As String
'FIRST WE DETERMINE WHAT DATE RANGE THE USER WANTS
varCANCEL = False
frmDATERANGE.Show 1
Me.Refresh
If varCANCEL Then Exit Sub
supervarS = CStr(varSTARTDATE)
supervarE = CStr(varENDDATE)
Set dbs = OpenDatabase(gsDatabase)
'NEXT WE SELECT OUT THOSE RECORDS FROM THE RELEVANT TABLE
'TABLES TEMP X,Y,Z ARE INTERMEDIATE STEP TABLES THE USER CAN VIEW
On Error Resume Next
dbs.Execute "DROP TABLE [TEMPX];"
Err.Clear
strSQL = "SELECT ACCOUNTNOFLD, DATEFLD INTO TEMPX " _
& "From THETABLE WHERE " _
& "(((THETABLE.DATEFLD)>=#" & supervarS & "#)) AND " _
& "(((THETABLE.DATEFLD)<=#" & supervarE & "#)) AND " _
& "(THETABLE.ANOTHERFLD) ='N';"
dbs.Execute (strSQL)
'THEN WE GET MORE DATA FROM ANOTHER TABLE
'BY USING THE IN-COMMON ACCOUNTNOFLD USING JOIN
On Error Resume Next
dbs.Execute "DROP TABLE [TEMPY];"
Err.Clear
strSQL = "SELECT * INTO TEMPY " _
& "From ANOTHERTBL INNER JOIN TEMPX ON " _
& "ANOTHERTBL.ACCOUNTNOFLD=TEMPX.ACCOUNTNOFLD;"
dbs.Execute (strSQL)
'NEXT WE ADD SOME NEW FIELDS
dbs.Execute ("ALTER TABLE TEMPY ADD COLUMN CUSTSUBSETFLD text")
dbs.Execute ("ALTER TABLE TEMPY ADD COLUMN ORDERSUBSETFLD text")
dbs.Close
'THEN POPULATE FIELDS WITH CUSTSUBSETFLD AND ORDERSUBSETFLD DATA
Set dbs = OpenDatabase(gsDatabase)
Set rstTEMPY = dbs.OpenRecordset("TEMPY")
Me.Refresh
Counter = 1
With rstTEMPY
.MoveFirst
While Not .EOF
.Edit
If Not IsNull(.THELARGERFLD) Then
.CUSTSUBSETFLD = CStr(Mid(.THELARGERFLD, 1, 11))
.ORDERSUBSETFLD = CStr(Mid(.THELARGERFLD, 15, 20))
Else
.CUSTSUBSETFLD = "None"
.ORDERSUBSETFLD = "None"
End If
.Update
Counter = Counter + 1
Debug.Print CStr(Counter)
.MoveNext
Wend
End With
rstTEMPY.Close
'INDEX TABLES SO CRYSTAL REPORTS WILL WORK
dbs.Execute "CREATE INDEX NewIndexX ON TEMPX (ACCOUNTNOFLD);"
dbs.Execute "CREATE INDEX NewIndexY ON TEMPY (ACCOUNTNOFLD);"
dbs.Close
Set rstTEMPY = Nothing
Set dbs = Nothing
'DEFINE REPORT
CR1.ReportFileName = "THEREPORT.rpt"
'PUT REPORT TITLE AND MONTH IN FORMULA FOR CRYSTAL REPORTS TO USE.
'CR1.Formulas(0) = "USERMONTH= " _
& "'" & theCurrentMonth & "'"
'RUN REPORT
CR1.Action = 1
Close
Set dbs = Nothing
End Sub 'END OF CREATE DATA AND PRINT REPORT USING A SPECIFIED DATE RANGEVisual Basic / VB / SQL / Access Code Examples
Private Sub cmdAnotherRpt_Click()
Dim dbs As Database
Dim strSQL As String
Dim TheSelectedMonth As String
varCANCEL = False
frmDATERANGE.Show 1
Me.Refresh
If varCANCEL Then Exit Sub
theCurrentMonth = "Blah Blah Report for " _
& CStr(Format(varENDDATE, "mmmm"))
thePrevMonthX = DateAdd("m", -1, varENDDATE)
ThePrevMonth = CStr(UCase(CStr(Format(thePrevMonthX, "mmm"))))
Set dbs = OpenDatabase(gsDatabase)
On Error Resume Next
dbs.Execute "DROP TABLE [TEMPX];"
Err.Clear
'Gets the code 2 data WITH THE APPROPRIATE MONTH FIELD
strSQL = "SELECT FLDA, FLDB, FLDC, FLDD, " _
& ThePrevMonth _
& " INTO TEMPX From SOURCETABLE " _
& "WHERE CODE = '2' AND OTHERFLD = 'Y';"
dbs.Execute (strSQL)
'create new field for the standard report
dbs.Execute ("ALTER TABLE Tempx ADD COLUMN PrevMonth integer")
'move thePrevMonth to new PrevMonth field
strSQL = "UPDATE TEMPX " _
& "SET PREVMONTH = " _
& ThePrevMonth _
& ";"
dbs.Execute (strSQL)
'PUT NAME OF MONTH IN TABLE FOR CRYSTAL REPORTS TO USE.
CR1.ReportFileName = "THEREPORT.rpt"
CR1.Formulas(0) = "USERMONTH= " _
& "'" & theCurrentMonth & "'"
CR1.Action = 1
Close
Set dbs = Nothing
End Sub 'end of cmdAnotherRpt buttonVisual Basic / VB / SQL / Access Code Examples
Private Sub cmdMonthEndDetailRpt_Click()
'DETAIL REPORT USING MULTIPLE TABLES
Dim dbs As Database
Dim strSQL As String
Dim TheSelectedMonth As String
varCANCEL = False
frmDATERANGE.Show 1
Me.Refresh
If varCANCEL Then Exit Sub
theCurrentMonth = "Month End Detail Report for " _
& CStr(Format(varENDDATE, "mmmm"))
thePrevMonthX = DateAdd("m", -1, varENDDATE)
ThePrevMonth = CStr(UCase(CStr(Format(thePrevMonthX, "mmm"))))
Set dbs = OpenDatabase(gsDatabase)
On Error Resume Next
dbs.Execute "DROP TABLE [TEMPX];"
Err.Clear
'Gets INVENFILE data WITH THE APPROPRIATE MONTH FIELD
strSQL = "SELECT SKU, DESC, ISSUEUNIT, VENDOR, CURR_BAL, " _
& ThePrevMonth _
& " INTO TEMPX From INVENFILE;"
dbs.Execute (strSQL)
'create new field for the standard report
dbs.Execute ("ALTER TABLE Tempx ADD COLUMN PrevMonth integer")
'move thePrevMonth to new PrevMonth field
strSQL = "UPDATE TEMPX " _
& "SET PREVMONTH = " _
& ThePrevMonth _
& ";"
dbs.Execute (strSQL)
'WE'VE CREATED THE TEMPX TABLE THAT CONTAINS THE INVENTORYFILE DATA.
'NOW WE CREATE THE ASSOCIATED TRANSACTION DATA.
supervarS = CStr(varSTARTDATE)
supervarE = CStr(varENDDATE)
'WE SELECT OUT THE MTD TRANSACTION RECORDS
On Error Resume Next
dbs.Execute "DROP TABLE [TEMPY];"
Err.Clear
strSQL = "SELECT SKU, TRANS_NUMBER, ORDERDATE, QTY, THETYPE, TRCODE INTO TEMPY " _
& "From TRANSACTION WHERE " _
& "(((TRANSACTION.ORDERDATE)>=#" & supervarS & "#)) AND " _
& "(((TRANSACTION.ORDERDATE)<=#" & supervarE & "#));"
dbs.Execute (strSQL)
'NOW WE PLOP IN THE REASON DESCRIPTIONS.
'create new field for the reason description.
dbs.Execute ("ALTER TABLE Tempy ADD COLUMN REASON text")
Set wrkJET = CreateWorkspace("", "admin", "", dbUseJet)
Set dbsCurrent = wrkJET.OpenDatabase(gsDatabase, True)
Set rstTEMPY = dbsCurrent.OpenRecordset("TEMPY")
Me.Refresh
With rstTEMPY
.MoveFirst
While Not .EOF
.Edit
Select Case .theTYPE 'Evaluate WMSCODE.
Case "A1"
.reason = "(+) Positive Adjustment"
Case "A2"
If .TRCODE = "62" Then .reason = "(-) Negative Adjustment"
If .TRCODE = "64" Then .reason = "(-) Broken/Damaged"
If .TRCODE = "61" Then .reason = "(-) Repackaging Adjustment"
Case "C1"
.reason = "(+) Customer Return"
Case "M2"
If .TRCODE = "82" Then .reason = "(-) Issue to Customer"
If .TRCODE = "80" Then .reason = "(-) Exception Order"
Case "P1"
.reason = "(+) Repack Finished Stock"
Case "P2"
.reason = "(-) Repack Bulk Stock"
Case "R1"
.reason = "(+) Receiving"
Case "R2"
.reason = "(-) Receiving Adjustment"
Case "V2"
.reason = "(-) Return to Vendor"
Case "V1"
.reason = "(+) Exchange from Vendor"
Case Else
.reason = "Unknown"
End Select
.Update
.MoveNext
Wend
End With
rstTEMPY.Close
dbsCurrent.Close
wrkJET.Close
Set rstTEMPY = Nothing
Set dbsCurrent = Nothing
Set wrkJET = Nothing
dbs.Execute "CREATE INDEX NewIndexX ON TEMPX (SKU);"
dbs.Execute "CREATE INDEX NewIndexY ON TEMPY (SKU);"
'DEFINE REPORT
CR1.ReportFileName = "MEDETAIL.rpt"
'PUT REPORT TITLE AND MONTH IN FORMULA FOR CRYSTAL REPORTS TO USE.
CR1.Formulas(0) = "USERMONTH= " _
& "'" & theCurrentMonth & "'"
'RUN REPORT
CR1.Action = 1
Close
Set dbs = Nothing
End Sub 'END OF cmdMonthEndDetailRptVisual Basic / VB / SQL / Access Code Examples
'CODE FOR A MULTIPLE QUERIES FORM
Private Sub cmdClose_Click()
Me.Hide
End Sub
'USE ANOTHER FORM TO GET DATE RANGE
Private Sub cmdDR_Click()
frmDATERANGE.Show
Me.Refresh
End Sub
Private Sub cmdReceipt_Click()
If varRO = "R" Then
varRO = ""
cmdReceipt.Caption = "Click for &Receipts Only (TR30 and TR36)"
Else
varRO = "R"
cmdReceipt.Caption = "Receipts Only Option Selected"
cmdOrder.Caption = "Click for &Orders Only (TR80 and TR82)"
cmdWorkOrder.Caption = "Click for &Work Orders Only (TR40)"
End If
End Sub
Private Sub cmdOrder_Click()
If varRO = "O" Then
varRO = ""
cmdOrder.Caption = "Click for &Orders Only (TR80 and TR82)"
Else
varRO = "O"
cmdOrder.Caption = "Orders Only Option Selected"
cmdReceipt.Caption = "Click for &Receipts Only (TR30 and TR36)"
cmdWorkOrder.Caption = "Click for &Work Orders Only (TR40)"
End If
End Sub
Private Sub cmdWorkOrder_Click()
If varRO = "W" Then
varRO = ""
cmdWorkOrder.Caption = "Click for &Work Orders Only (TR40)"
Else
varRO = "W"
cmdWorkOrder.Caption = "Work Orders Only Option Selected"
cmdReceipt.Caption = "Click for &Receipts Only (TR30 and TR36)"
cmdOrder.Caption = "Click for &Orders Only (TR80 and TR82)"
End If
End Sub
Private Sub cmdReset_Click()
varRO = ""
cmdReceipt.Caption = "Click for &Receipts Only (TR30 and TR36)"
cmdOrder.Caption = "Click for &Orders Only (TR80 and TR82)"
cmdWorkOrder.Caption = "Click for &Work Orders Only (TR40)"
varDR = False
varSingleSKU = ""
txtSKU.Text = ""
varSingleAcctCode = ""
txtACCOUNTCODE.Text = ""
varSinglePOnumber = ""
txtPOnumber.Text = ""
End Sub
Private Sub cmdSEARCH_click(x)
End Sub
Private Sub cmdSEARCHX_Click()
Dim dbs As Database
Set dbs = OpenDatabase(gsDatabase)
cmdSEARCHX.Caption = "Working..."
'First we select out the user requested date range.
Me.Refresh
On Error Resume Next
dbs.Execute "DROP TABLE [TEMPX];"
Err.Clear
If varDR Then 'get the specified date range
supervarS = CStr(varSTARTDATE)
supervarE = CStr(varENDDATE)
strSQL = "SELECT * INTO TEMPX " _
& "From TRANSACTION WHERE " _
& "(((TRANSACTION.THEDATE)>=#" & supervarS & "#)) AND " _
& "(((TRANSACTION.THEDATE)<=#" & supervarE & "#));"
dbs.Execute (strSQL)
Else 'make copy of entire transaction file
strSQL = "SELECT * INTO TEMPX From TRANSACTION;"
dbs.Execute (strSQL)
End If
'Next we check if user wants Receipt-Only, Orders-Only, Work Orders-Only or all.
On Error Resume Next
dbs.Execute "DROP TABLE [TEMPY];"
Err.Clear
If varRO = "R" Then 'get receipts only
strSQL = "SELECT * INTO TEMPY " _
& "From TEMPX WHERE " _
& "TEMPX.TRCODE = '30' OR TEMPX.TRCODE = '36';"
dbs.Execute (strSQL)
Else
End If
If varRO = "O" Then 'get orders only
strSQL = "SELECT * INTO TEMPY " _
& "From TEMPX WHERE " _
& "TEMPX.theTYPE = 'M2' OR TEMPX.theTYPE = 'M3';"
dbs.Execute (strSQL)
Else
End If
If varRO = "W" Then 'get work orders only
strSQL = "SELECT * INTO TEMPY " _
& "From TEMPX WHERE " _
& "TEMPX.TRCODE = '40';"
dbs.Execute (strSQL)
Else
End If
If varRO = "" Then 'keep everything
strSQL = "SELECT * INTO TEMPY From TEMPX;"
dbs.Execute (strSQL)
Else
End If
'We've taken care of the dateRange and the R vs O scenarios
'Next let's do the Single Account
On Error Resume Next
dbs.Execute "DROP TABLE [TEMPZ];"
Err.Clear
If txtACCOUNTCODE.Text = "" Then 'user doesn't want a single account
strSQL = "SELECT * INTO TEMPZ From TEMPY;"
dbs.Execute (strSQL)
Else 'user wants data only for a single account
varSingleAcctCode = CStr(txtACCOUNTCODE.Text)
strSQL = "SELECT * INTO TEMPZ " _
& "From TEMPY WHERE " _
& "(((TEMPY.ACCTCODE)='" & varSingleAcctCode & "'));"
dbs.Execute (strSQL)
End If
'Now let's do the single P.O.
On Error Resume Next
dbs.Execute "DROP TABLE [TEMPX];"
Err.Clear
If txtPOnumber.Text = "" Then 'user doesn't want a single P.O. number
strSQL = "SELECT * INTO TEMPX From TEMPZ;"
dbs.Execute (strSQL)
Else 'user wants data only for a P.O.
varSinglePOnumber = CStr(txtPOnumber.Text)
strSQL = "SELECT * INTO TEMPX " _
& "From TEMPZ WHERE " _
& "(((TEMPZ.PO_NUMBER)='" & varSinglePOnumber & "'));"
dbs.Execute (strSQL)
End If
'Last is the single SKU scenario,
'this calls for a different output than the rest
If txtSKU.Text = "" Then 'processing is done, show output to user
frmX.Show
Else 'this is the single SKU scenario, processing continues
'first we get the records for the requested SKU
On Error Resume Next
dbs.Execute "DROP TABLE [TEMPY];"
Err.Clear
varSingleSKU = CStr(txtSKU.Text)
strSQL = "SELECT * INTO TEMPY " _
& "From TEMPX WHERE " _
& "(((TEMPX.SKU)='" & varSingleSKU & "'));"
dbs.Execute (strSQL)
'next we get the SKU description, etc. data
On Error Resume Next
dbs.Execute "DROP TABLE [TEMPZ];"
Err.Clear
strSQL = "SELECT * INTO TEMPZ " _
& "From TEMPY INNER JOIN THESKUFILE ON " _
& "TEMPY.SKU=THESKUFILE.SKU;"
dbs.Execute (strSQL)
frmZ.Show
End If
endOfJobHK:
cmdSEARCH.Caption = "Search and Display Results"
dbs.Close
Set dbs = Nothing
End Sub
Private Sub Form_Load()
varRO = ""
cmdReceipt.Caption = "Click for &Receipts Only (TR30 and TR36)"
cmdOrder.Caption = "Click for &Orders Only (TR80 and TR82)"
cmdWorkOrder.Caption = "Click for &Work Orders Only (TR40)"
varDR = False
varSingleSKU = ""
txtSKU.Text = ""
varSingleAcctCode = ""
txtACCOUNTCODE.Text = ""
varSinglePOnumber = ""
txtPOnumber.Text = ""
End Sub 'END OF CODE FOR A QUERIES FORMVisual Basic / VB / SQL / Access Code Examples
Private Sub cmdOPTIMIZE_Click() 'COMPACT THE ACCESS DATABASE ----------------------------------
Dim tempvar As String
Dim tempvarX As String
Dim fileName As String
Dim dirFileName As String
Dim SourceFile, DestinationFile
Close
Set dbs = Nothing
Set SourceFile = Nothing
Set DestinationFile = Nothing
'Set status bar.
With sbStatusBar
'This text will be displayed when the StatusBar is in Simple style.
.Style = sbrNormal ' Normal style.
.SimpleText = "Working..."
.Style = sbrSimple ' Simple style.
Refresh
End With
'Create backup file name.
tempvar = "XX"
tempvarX = Trim(Str(Format(Date, "mmddyy")))
fileName = tempvar + tempvarX + ".mdb"
dirFileName = "XXXBU\" + fileName
'Make sure there isn't already a file with the name of the compacted database.
On Error GoTo errorRTN2
If Dir(dirFileName) <> "" Then Kill dirFileName
'Makes temp backup before optimization.
On Error GoTo errorRTN2
If Dir("tempBU.mdb") <> "" Then Kill "tempBU.mdb"
SourceFile = "XXX.mdb" 'Define source file name.
DestinationFile = "tempBU.mdb" 'Define target file name.
On Error GoTo errorRTN2
FileCopy SourceFile, DestinationFile ' Copy source to target.
'Compacts (optimizes) the database.
On Error GoTo errorRTN2
DBEngine.CompactDatabase "XXX.mdb", dirFileName
'Copies optimized database over the original.
On Error GoTo errorRTN2
If Dir("XXX.mdb") <> "" Then Kill "CST.mdb"
SourceFile = dirFileName 'Define source file name.
DestinationFile = "XXX.mdb" 'Define target file name.
On Error GoTo errorRTN2
FileCopy SourceFile, DestinationFile ' Copy source to target.
MsgBox ("Database optimized and a " + dirFileName + " backup copy made.")
Close
tempvar = ""
tempvarX = ""
fileName = ""
dirFileName = ""
Set SourceFile = Nothing
Set DestinationFile = Nothing
Exit Sub
errorRTN2:
MsgBox ("File conflict problem. Exit/Restart application and try again.")
End Sub 'END OF OPTIMIZE/COMPACT PROGRAMVisual Basic / VB / SQL / Access Code Examples
Private Sub cmdBACKUPdatabase_Click() 'BACKUP THE DATABASE -------------------------------------
Dim tempvar As String
Dim tempvarX As String
Dim fileName As String
Dim dirFileName As String
Dim SourceFile, DestinationFile
Close
tempvar = ""
tempvarX = ""
fileName = ""
dirFileName = ""
Set dbs = Nothing
Set SourceFile = Nothing
Set DestinationFile = Nothing
'Set status bar.
With sbStatusBar
' This text will be displayed when the StatusBar is in Simple style.
.Style = sbrNormal ' Normal style.
.SimpleText = "Working..."
.Style = sbrSimple ' Simple style.
Refresh
End With
'Create backup file name.
tempvar = "XX"
tempvarX = Trim(Str(Format(Date, "mmddyy")))
fileName = tempvar + tempvarX + ".mdb"
dirFileName = "XXBU\" + fileName
'Make sure there isn't already a file with the name of the backup file.
If Dir(dirFileName) <> "" Then Kill dirFileName
' Make the Backup.
SourceFile = "XX.mdb" 'Define source file name.
DestinationFile = dirFileName 'Define target file name.
On Error GoTo errorRTN
FileCopy SourceFile, DestinationFile ' Copy source to target.
Me.sbStatusBar.Style = sbrNormal ' Normal style.
MsgBox ("A Backup copy named " + dirFileName + " has been made.")
Close
tempvar = ""
tempvarX = ""
fileName = ""
dirFileName = ""
Set SourceFile = Nothing
Set DestinationFile = Nothing
'Me.Hide
'Me.Show
Exit Sub
errorRTN:
MsgBox ("File conflict problem. Exit/Restart application and try again.")
End Sub 'END OF DATABASE BACKUP PROGRAMVisual Basic / VB / SQL / Access Code Examples
'=======================================================
'PRINT FORM CODE
Private Sub cmdPrintScreen_Click()
Me.PrintForm
End Sub
'=======================================================
'EXIT APPLICATION CODE
Private Sub cmdEXIT_Click() 'EXIT APPLICATION
End
End Sub 'END OF EXIT AP
'=======================================================
'LOGIN AND PASSWORD CODE
'Use Wizard
'=======================================================Companion Code:
VB / SQL / MS Access Code-Examples II of II (Business Application Code)
Comments
thx 4 posting dude
nice post ........
Hi paradigmsearch,
Very informative post .... I love java language .... But was studying how other frameworks work .... Good hub ... well done .... keep the good work up .....
Thanks
JOHN 9 months ago
thank you very much for all this information