home *** CD-ROM | disk | FTP | other *** search
/ Master 95 #1 / MASTER95_1.iso / microsof / vbasic4 / vb4-6.cab / visdata.bas < prev    next >
Encoding:
BASIC Source File  |  1995-07-26  |  62.0 KB  |  2,011 lines

  1. Attribute VB_Name = "modVisData"
  2. '------------------------------------------------------------
  3. ' VISDATA.BAS
  4. ' support functions for the Visual Data sample application
  5. '
  6. ' General Information: This app is intended to demonstrate
  7. '   and exercise all of the functionality available in the
  8. '   DAO (Data Access Objects) in VB 4.0.
  9. '
  10. '------------------------------------------------------------
  11.  
  12. Option Explicit
  13.  
  14. 'api declarations
  15. #If Win16 Then
  16.     Declare Function OSGetPrivateProfileString% Lib "KERNEL" Alias "GetPrivateProfileString" (ByVal AppName$, ByVal KeyName$, ByVal keydefault$, ByVal ReturnString$, ByVal NumBytes As Integer, ByVal FileName$)
  17.     Declare Function OSWritePrivateProfileString% Lib "KERNEL" Alias "WritePrivateProfileString" (ByVal AppName$, ByVal KeyName$, ByVal keydefault$, ByVal FileName$)
  18.     Declare Function OSWinHelp% Lib "User" Alias "WinHelp" (ByVal hwnd%, ByVal HelpFile$, ByVal wCommand%, dwData As Any)
  19.     Declare Function OSTimeGetTime& Lib "MMSYSTEM.DLL" Alias "TimeGetTime" ()
  20.     Declare Function SQLAllocEnv% Lib "ODBC.DLL" (env As Long)
  21.     Declare Function SQLDataSources% Lib "ODBC.DLL" (ByVal henv&, ByVal fdir%, ByVal szDSN$, ByVal cbDSNMAx%, pcbDSN%, ByVal szDesc$, ByVal cbDescMax%, pcbDesc%)
  22. #Else
  23.     Declare Function OSGetPrivateProfileString% Lib "Kernel32" Alias "GetPrivateProfileStringA" (ByVal AppName$, ByVal KeyName$, ByVal keydefault$, ByVal ReturnString$, ByVal NumBytes As Integer, ByVal FileName$)
  24.     Declare Function OSWritePrivateProfileString% Lib "Kernel32" Alias "WritePrivateProfileStringA" (ByVal AppName$, ByVal KeyName$, ByVal keydefault$, ByVal FileName$)
  25.     Declare Function OSWinHelp% Lib "USER32" Alias "WinHelpA" (ByVal hwnd&, ByVal HelpFile$, ByVal wCommand%, dwData As Any)
  26.     Declare Function OSTimeGetTime& Lib "WINMM.DLL" Alias "timeGetTime" ()
  27.     Declare Function SQLAllocEnv% Lib "ODBC32.DLL" (env&)
  28.     Declare Function SQLDataSources% Lib "ODBC32.DLL" (ByVal henv&, ByVal fdir%, ByVal szDSN$, ByVal cbDSNMAx%, pcbDSN%, ByVal szDesc$, ByVal cbDescMax%, pcbDesc%)
  29. #End If
  30.  
  31. 'global object variables
  32. Global gwsMainWS As Workspace       'main workspace object
  33. Global gdbCurrentDB As Database     'main database object
  34. Global gbDBOpenFlag As Integer      'flag to know if a db is open
  35. Global gPropObject As Object        'object to show properties on
  36. Global gDataCtlObj As Object        'global data control object
  37. Global gtdfTableDef As TableDef     'global tabledef used by frmTblStruct
  38. Global gnFormType As Integer        'form type chosen on main form
  39.                                     '0 = data control
  40.                                     '1 = no data control
  41.                                     '2 = grid control
  42. Global gnRecordsetType As Integer   'recordset type chosen on main form
  43.                                     '0 = table
  44.                                     '1 = dynaset
  45.                                     '2 = snapshot
  46.  
  47. 'global database variables
  48. Global gsDataType As String         'data backend = connect string
  49.                                     'for everything accept Access
  50. Global gsDBName As String           'current database name
  51. Global gsODBCDatasource As String   'global odbc values
  52. Global gsODBCDatabase As String     '       "
  53. Global gsODBCUserName As String     '       "
  54. Global gsODBCPassword As String     '       "
  55. Global gsDynaString As String       'global sql statament
  56. Global gsTblName As String          '
  57. Global glQueryTimeout As Long       '
  58. Global glLoginTimeout As Long       '
  59. Global gsTableDynaFilter As String  '
  60. Global gnReadOnly As Integer        'database readonly flag
  61.  
  62. 'other global vars
  63. Global gobjIDEAppInst As Object     'add-in variable
  64. Global gsZoomData As String         'pass info to the zoom form
  65. Global gsNewLine As String          'CRLF holder
  66.  
  67. 'multi user variables
  68. Global gnMURetryCnt As Integer
  69. Global gnMUDelay As Integer
  70. Global gnMULocking As Integer       'flag for pessimistic or optimistic locking
  71.  
  72. 'global find values used to pass info between
  73. 'the dynaset form and find dialog
  74. Global gbFindFailed As Integer
  75. Global gsFindExpr As String
  76. Global gsFindOp As String
  77. Global gsFindField As String
  78. Global gnFindType As Integer
  79. Global gbFromTableView As Integer
  80.  
  81. 'global seek values used to pass info between
  82. 'the table form and find dialog
  83. Global gsSeekOperator As String
  84. Global gsSeekValue As String
  85.  
  86. 'global flags
  87. Global gbDBChanged As Integer       '
  88. Global gbTransPending As Integer    'used for transaction management
  89. Global gbFromSQL As Integer         'source of sql statement was SQL form
  90. Global gbAddTableFlag As Integer    'new or design designator
  91. Global gbSettingDataCtl As Integer  'used to reset data control props
  92.  
  93. 'data backend types used as the connect string
  94. Global Const gsJETMDB = "Jet Engine MDB"
  95. Global Const gsDBASEIII = "Dbase III;"
  96. Global Const gsDBASEIV = "Dbase IV;"
  97. Global Const gsFOXPRO20 = "FoxPro 2.0;"
  98. Global Const gsFOXPRO25 = "FoxPro 2.5;"
  99. Global Const gsFOXPRO26 = "FoxPro 2.6;"
  100. Global Const gsPARADOX3X = "Paradox 3.X;"
  101. Global Const gsPARADOX4X = "Paradox 4.X;"
  102. Global Const gsBTRIEVE = "Btrieve;"
  103. Global Const gsEXCEL30 = "Excel 3.0;"
  104. Global Const gsEXCEL40 = "Excel 4.0;"
  105. Global Const gsEXCEL50 = "Excel 5.0;"
  106. Global Const gsTEXTFILES = "Text;"
  107. Global Const gsSQLDB = "ODBC;"
  108.  
  109. 'global constants
  110. Global Const gsVISDATA4 = "VISDATA4"          'general ini file section
  111. Global Const gsVISDATAINI = "VISDATA.INI"     '
  112. Global Const gsDEFAULT_DRIVER = "SQL Server"  'used for registerdatabase
  113. Global Const gnMSGBOX_YES = 6                 'return from msgbox
  114. Global Const gnMSGBOX_TYPE = 4 + 48 + 256     'yes/no buttons with no as default
  115. Global Const gnEOF_ERR = 626                  '
  116. Global Const gnFTBLS = 0                      '
  117. Global Const gnFFLDS = 1                      '
  118. Global Const gnFINDX = 2                      '
  119. Global Const gnMAX_GRID_ROWS = 31999          '
  120. Global Const gnMAX_MEMO_SIZE = 20000          '
  121. Global Const gnGETCHUNK_CUTOFF = 50           '
  122. Global Const gsNULL_STR = ""                  '
  123. Global Const gnDATACTL_FORM = 0               '
  124. Global Const gnNODATACTL_FORM = 1             '
  125. Global Const gnDATAGRID_FORM = 2              '
  126. Global Const gnRS_PASSTHRU = 8                '
  127. Global Const gnCTLARRAYHEIGHT = 340&          '
  128. Global Const gnSCREEN = 0                     'used to center forms on screen
  129. Global Const gnMDIFORM = 1                    'used to center forms on frmMDI
  130.  
  131.  
  132. '------------------------------------------------------------
  133. 'this function returns the type of querydef
  134. 'for the item selected in the querydefs
  135. 'list on the frmTables form
  136. '------------------------------------------------------------
  137. Function ActionQueryType() As String
  138.   Dim qdf As QueryDef
  139.   
  140.   Set qdf = gdbCurrentDB.QueryDefs(frmTables.lstQueryDefs.Text)
  141.   
  142.   'check to see if it is an action query
  143.   If (qdf.Type And dbQAction) = 0 Then
  144.     ActionQueryType = gsNULL_STR
  145.     Exit Function
  146.   End If
  147.   
  148.   'must be an action query type
  149.   Select Case qdf.Type
  150.     Case dbQCrosstab
  151.       ActionQueryType = "Cross Tab"
  152.     Case dbQDelete
  153.       ActionQueryType = "Delete"
  154.     Case dbQUpdate
  155.       ActionQueryType = "Update"
  156.     Case dbQAppend
  157.       ActionQueryType = "Append"
  158.     Case dbQMakeTable
  159.       ActionQueryType = "Make Table"
  160.     Case dbQDDL
  161.       ActionQueryType = "DDL"
  162.     Case dbQSQLPassThrough
  163.       ActionQueryType = "SQLPassThrough"
  164.     Case dbQSetOperation
  165.       ActionQueryType = "Set Operation"
  166.     Case dbQSPTBulk
  167.       ActionQueryType = "SPT Bulk"
  168.     Case Else
  169.       ActionQueryType = gsNULL_STR
  170.   End Select
  171.  
  172. End Function
  173.  
  174. '------------------------------------------------------------
  175. 'this functions adds [] to object names that might need
  176. 'them because they have spaces in them
  177. '------------------------------------------------------------
  178. Function AddBrackets(rObjName As String) As String
  179.   'add brackets to object names w/ spaces in them
  180.   If InStr(rObjName, " ") > 0 And Mid(rObjName, 1, 1) <> "[" Then
  181.     AddBrackets = "[" & rObjName & "]"
  182.   Else
  183.     AddBrackets = rObjName
  184.   End If
  185. End Function
  186.  
  187. Sub CenterMe(rfrm As Object, rwScreenMDI As Integer)
  188.   On Error Resume Next
  189.   
  190.   If rwScreenMDI = gnSCREEN Then
  191.     'center it on the screen
  192.     rfrm.Top = (Screen.Height - rfrm.Height) \ 2
  193.     rfrm.Left = (Screen.Width - rfrm.Width) \ 2
  194.   Else
  195.     'center it on the MDI form
  196.     If rfrm.MDIChild = True Then
  197.       rfrm.Top = ((frmMDI.Height - rfrm.Height) \ 2) - 800
  198.       rfrm.Left = (frmMDI.Width - rfrm.Width) \ 2
  199.     Else
  200.       rfrm.Top = frmMDI.Top + (frmMDI.Height - rfrm.Height) \ 2
  201.       rfrm.Left = frmMDI.Left + (frmMDI.Width - rfrm.Width) \ 2
  202.     End If
  203.   End If
  204.   
  205. End Sub
  206.  
  207. '------------------------------------------------------------
  208. 'this function checks to see if a transaction is pending
  209. 'and displays a message is one is
  210. '------------------------------------------------------------
  211. Function CheckTransPending(msg As String) As Integer
  212.  
  213.   If gbTransPending = True Then
  214.     MsgBox msg & gsNewLine & "Execute Commit or Rollback First.", 48
  215.     CheckTransPending = True
  216.   Else
  217.     CheckTransPending = False
  218.   End If
  219.  
  220. End Function
  221.  
  222. '------------------------------------------------------------
  223. 'clear out the data fields on the table and dynasnap forms
  224. '------------------------------------------------------------
  225. Sub ClearDataFields(frm As Form, nCnt As Integer)
  226.   Dim i As Integer
  227.  
  228.   'clear out the fields on the main form
  229.   For i = 0 To nCnt - 1
  230.     frm.txtFieldData(i).Text = gsNULL_STR
  231.   Next
  232. End Sub
  233.  
  234. '------------------------------------------------------------
  235. 'this sub closes all frmDynaSnap, frmTableObj and frmDataGrid
  236. 'forms by looking for forms with a Tag set to "Recordset"
  237. '------------------------------------------------------------
  238. Sub CloseAllRecordsets()
  239.   Dim i As Integer
  240.  
  241.   MsgBar "Closing Recordsets", True
  242.   While i < Forms.Count
  243.     If Forms(i).Tag = "Recordset" Then
  244.       Unload Forms(i)
  245.     Else
  246.       i = i + 1
  247.     End If
  248.   Wend
  249.   MsgBar gsNULL_STR, False
  250.  
  251. End Sub
  252.  
  253. '------------------------------------------------------------
  254. 'this sub closes all frmListCombo forms by looking for
  255. 'forms with a Tag set to "ListCombo"
  256. '------------------------------------------------------------
  257. Sub CloseAllListCombos()
  258.   Dim i As Integer
  259.  
  260.   MsgBar "Closing List/Combo Forms", True
  261.   While i < Forms.Count
  262.     If Forms(i).Tag = "ListCombo" Then
  263.       Unload Forms(i)
  264.     Else
  265.       i = i + 1
  266.     End If
  267.   Wend
  268.   MsgBar gsNULL_STR, False
  269.  
  270. End Sub
  271.  
  272. '------------------------------------------------------------
  273. 'this function copies data from one table to another
  274. 'from the frmCopyStruct form
  275. 'It demonstrates the use of transactions to speed up this
  276. 'type of operation
  277. '------------------------------------------------------------
  278. Function CopyData(rFromDB As Database, rToDB As Database, rFromName As String, rToName As String) As Integer
  279.   On Error GoTo CopyErr
  280.  
  281.   Dim recRecordset1 As Recordset, recRecordset2 As Recordset
  282.   Dim i As Integer
  283.   Dim nRC As Integer
  284.   Dim fld As Field
  285.  
  286.   'open both recordsets
  287.   Set recRecordset1 = rFromDB.OpenRecordset(rFromName)
  288.   Set recRecordset2 = rToDB.OpenRecordset(rToName)
  289.   gwsMainWS.BeginTrans
  290.   While recRecordset1.EOF = False
  291.     recRecordset2.AddNew
  292.     'this loop copies the data from each field to
  293.     'the new table
  294. '    For Each fld In recRecordset1.Fields
  295.     For i = 0 To recRecordset1.Fields.Count - 1
  296.       Set fld = recRecordset1.Fields(i)
  297.       recRecordset2(fld.Name).Value = fld.Value
  298.     Next
  299.     recRecordset2.Update
  300.     recRecordset1.MoveNext
  301.     nRC = nRC + 1
  302.     'this test will commit transactions every 1000 records
  303.     If nRC = 1000 Then
  304.       gwsMainWS.CommitTrans
  305.       gwsMainWS.BeginTrans
  306.       nRC = 0
  307.     End If
  308.   Wend
  309.   gwsMainWS.CommitTrans
  310.  
  311.   CopyData = True
  312.   Exit Function
  313.  
  314. CopyErr:
  315.   gwsMainWS.Rollback
  316.   ShowError
  317.   CopyData = False
  318.   Exit Function
  319.  
  320. End Function
  321.  
  322. '------------------------------------------------------------
  323. 'this function copies the structure of one table to
  324. 'a new table in the same or different database
  325. '------------------------------------------------------------
  326. Function CopyStruct(vFromDB As Database, vToDB As Database, vFromName As String, vToName As String, bCreateIndex As Integer) As Integer
  327.   On Error GoTo CSErr
  328.  
  329.   Dim i As Integer
  330.   Dim tblTableDefObj As TableDef
  331.   Dim fldFieldObj As Field
  332.   Dim indIndexObj As Index
  333.   Dim tdf As TableDef
  334.   Dim fld As Field
  335.   Dim idx As Index
  336.   
  337.   'search to see if table exists
  338. NameSearch:
  339. '  For Each tdf In vToDB.Tabledefs
  340.   For i = 0 To vToDB.TableDefs.Count - 1
  341.     Set tdf = vToDB.TableDefs(i)
  342.     If UCase(tdf.Name) = UCase(vToName) Then
  343.       If MsgBox(vToName & " already exists, delete it?", 4) = gnMSGBOX_YES Then
  344.          vToDB.TableDefs.Delete tdf.Name
  345.       Else
  346.          vToName = InputBox("Enter New Table Name:")
  347.          If Len(vToName) = 0 Then
  348.            Exit Function
  349.          Else
  350.            GoTo NameSearch
  351.          End If
  352.       End If
  353.       Exit For
  354.     End If
  355.   Next
  356.   
  357.   Set tblTableDefObj = gdbCurrentDB.CreateTableDef()
  358.     
  359.   'strip off owner if needed
  360.   tblTableDefObj.Name = StripOwner(vToName)
  361.  
  362.   'create the fields
  363. '  For Each fld In vFromDB.Tabledefs(vFromName).Fields
  364.   For i = 0 To vFromDB.TableDefs(vFromName).Fields.Count - 1
  365.     Set fld = vFromDB.TableDefs(vFromName).Fields(i)
  366.     Set fldFieldObj = vFromDB.TableDefs(vFromName).CreateField(fld.Name, fld.Type, fld.Size)
  367.     tblTableDefObj.Fields.Append fldFieldObj
  368.   Next
  369.  
  370.   'create the indexes
  371.   If bCreateIndex <> False Then
  372. '    For Each idx In vFromDB.Tabledefs(vFromName).Indexes
  373.     For i = 0 To vFromDB.TableDefs(vFromName).Indexes.Count - 1
  374.       Set idx = vFromDB.TableDefs(vFromName).Indexes(i)
  375.       Set indIndexObj = vFromDB.TableDefs(vFromName).CreateIndex(idx.Name)
  376.       With indIndexObj
  377.         indIndexObj.Fields = idx.Fields
  378.         indIndexObj.Unique = idx.Unique
  379.         If gsDataType <> gsSQLDB Then
  380.           indIndexObj.Primary = idx.Primary
  381.         End If
  382.       End With
  383.       tblTableDefObj.Indexes.Append indIndexObj
  384.     Next
  385.   End If
  386.  
  387.   'append the new table
  388.   vToDB.TableDefs.Append tblTableDefObj
  389.  
  390.   CopyStruct = True
  391.   Exit Function
  392.  
  393. CSErr:
  394.   ShowError
  395.   CopyStruct = False
  396.   Exit Function
  397.  
  398. End Function
  399.  
  400. '------------------------------------------------------------
  401. 'sub used to create a sample table and fill it
  402. 'with NumbRecs number of rows
  403. 'can only be called from the debug window
  404. 'for example:
  405. 'CreateSampleTable "mytbl",100
  406. '------------------------------------------------------------
  407. Sub CreateSampleTable(TblName As String, NumbRecs As Long)
  408.   Dim rec As Recordset
  409.   Dim ii As Long
  410.   Dim nCnt As Integer
  411.   Dim tdf As TableDef
  412.   Dim fld As Field
  413.   Dim idx As Index
  414.  
  415.   'create the data holding table
  416.   Set tdf = gdbCurrentDB.CreateTableDef(TblName)
  417.   
  418.   Set fld = tdf.CreateField("name", dbText, 25)
  419.   tdf.Fields.Append fld
  420.   
  421.   Set fld = tdf.CreateField("address", dbText, 25)
  422.   tdf.Fields.Append fld
  423.  
  424.   Set fld = tdf.CreateField("record", dbText, 10)
  425.   tdf.Fields.Append fld
  426.   
  427.   Set fld = tdf.CreateField("id", dbLong)
  428.   tdf.Fields.Append fld
  429.  
  430.   'add the indexes
  431.   Set idx = tdf.CreateIndex(TblName & "1")
  432.   idx.Fields = "name"
  433.   idx.Unique = False
  434.   tdf.Indexes.Append idx
  435.  
  436.   Set idx = tdf.CreateIndex(TblName & "2")
  437.   idx.Fields = "id"
  438.   idx.Unique = True
  439.   tdf.Indexes.Append idx
  440.  
  441.   gdbCurrentDB.TableDefs.Append tdf
  442.  
  443.   'add records to the table in reverse order
  444.   'so indexes have some work to do
  445.   Set rec = gdbCurrentDB.OpenRecordset(TblName)
  446.   nCnt = 0
  447.   gwsMainWS.BeginTrans
  448.   For ii = NumbRecs To 1 Step -1
  449.     rec.AddNew
  450.     rec(0) = "name" & ii
  451.     rec(1) = "addr" & ii
  452.     rec(2) = "rec" & ii
  453.     rec(3) = ii
  454.     rec.Update
  455.     nCnt = nCnt + 1
  456.     If nCnt = 1000 Then
  457.       gwsMainWS.CommitTrans
  458.       gwsMainWS.BeginTrans
  459.       nCnt = 0
  460.     End If
  461.   Next
  462.   gwsMainWS.CommitTrans
  463.  
  464. End Sub
  465.  
  466. '------------------------------------------------------------
  467. 'this function fills a list or combo box with the
  468. 'tables (and querydefs) from the Tables form
  469. 'ItemData is set to 0 for a tabledef and 1 for a querydef
  470. '------------------------------------------------------------
  471. Sub GetTableList(rctl As Control, rbIncludeQDFs As Integer, rbIncludeSys As Integer, rbStripConnect As Integer)
  472.   On Error GoTo FTLErr
  473.   
  474.   Dim i As Integer
  475.   Dim sTmp As String
  476.   
  477.   'add the tabledefs
  478.   For i = 0 To frmTables.lstTables.ListCount - 1
  479.     sTmp = frmTables.lstTables.List(i)
  480.     If rbIncludeSys = True Then
  481.       If rbStripConnect = True Then
  482.         rctl.AddItem StripConnect(sTmp)
  483.       Else
  484.         rctl.AddItem sTmp
  485.       End If
  486.       rctl.ItemData(rctl.NewIndex) = 0
  487.     Else
  488.       If (gdbCurrentDB.TableDefs(StripConnect(sTmp)).Attributes And dbSystemObject) = 0 Then
  489.         If rbStripConnect = True Then
  490.           rctl.AddItem StripConnect(sTmp)
  491.         Else
  492.           rctl.AddItem sTmp
  493.         End If
  494.         rctl.ItemData(rctl.NewIndex) = 0
  495.       End If
  496.     End If
  497.   Next
  498.   
  499.   'add the querydefs
  500.   If rbIncludeQDFs = True Then
  501.     For i = 0 To frmTables.lstQueryDefs.ListCount - 1
  502.       rctl.AddItem frmTables.lstQueryDefs.List(i)
  503.       rctl.ItemData(rctl.NewIndex) = 1
  504.     Next
  505.   End If
  506.   
  507.   Exit Sub
  508.   
  509. FTLErr:
  510.   ShowError
  511.   Exit Sub
  512.  
  513. End Sub
  514.  
  515. '------------------------------------------------------------
  516. 'this function returns the numeric field type
  517. 'for the passed in string
  518. '------------------------------------------------------------
  519. Function GetFieldType(rFldType As String) As Integer
  520.   'return field length
  521.   If rFldType = "Text" Then
  522.     GetFieldType = dbText
  523.   Else
  524.     Select Case rFldType
  525.       Case "Counter"
  526.         GetFieldType = dbLong
  527.       Case "Boolean"
  528.         GetFieldType = dbBoolean
  529.       Case "Byte"
  530.         GetFieldType = dbByte
  531.       Case "Integer"
  532.         GetFieldType = dbInteger
  533.       Case "Long"
  534.         GetFieldType = dbLong
  535.       Case "Currency"
  536.         GetFieldType = dbCurrency
  537.       Case "Single"
  538.         GetFieldType = dbSingle
  539.       Case "Double"
  540.         GetFieldType = dbDouble
  541.       Case "Date/Time"
  542.         GetFieldType = dbDate
  543.       Case "Binary"
  544.         GetFieldType = dbLongBinary
  545.       Case "Memo"
  546.         GetFieldType = dbMemo
  547.     End Select
  548.   End If
  549.  
  550. End Function
  551.  
  552. '------------------------------------------------------------
  553. 'this function returns an appropriate field width for the
  554. 'field type passed in to be used for the control width on
  555. 'frmDynaSnap and frmTableObj forms
  556. '------------------------------------------------------------
  557. Function GetFieldWidth(rType As Integer)
  558.   Select Case rType
  559.     Case dbBoolean
  560.       GetFieldWidth = 850
  561.     Case dbByte
  562.       GetFieldWidth = 650
  563.     Case dbInteger
  564.       GetFieldWidth = 900
  565.     Case dbLong
  566.       GetFieldWidth = 1100
  567.     Case dbCurrency
  568.       GetFieldWidth = 1800
  569.     Case dbSingle
  570.       GetFieldWidth = 1800
  571.     Case dbDouble
  572.       GetFieldWidth = 2200
  573.     Case dbDate
  574.       GetFieldWidth = 2000
  575.     Case dbText
  576.       GetFieldWidth = 3250
  577.     Case dbLongBinary
  578.       GetFieldWidth = 3250
  579.     Case dbMemo
  580.       GetFieldWidth = 3250
  581.     Case Else
  582.       GetFieldWidth = 3250
  583.   End Select
  584.  
  585. End Function
  586.  
  587. '------------------------------------------------------------
  588. 'this function returns the INI file setting for the
  589. 'passed in item and section
  590. '------------------------------------------------------------
  591. Function GetINIString(ByVal vsItem As String, ByVal vsDefault As String, ByVal vsSection As String) As String
  592.   GetINIString = GetSetting("VisData", vsSection, vsItem, vsDefault)
  593. End Function
  594.  
  595. '------------------------------------------------------------
  596. 'this function returns the number of records in a
  597. 'recordset of any type
  598. '------------------------------------------------------------
  599. Function GetNumbRecs(rrsRecSet As Recordset) As Long
  600.   Dim rsClone As Recordset
  601.  
  602.   On Error GoTo GNRErr
  603.  
  604.   MsgBar "Calculating Number of Rows in Recordset", True
  605.  
  606.   If rrsRecSet.Type = dbOpenTable Then
  607.     GetNumbRecs = rrsRecSet.RecordCount
  608.   Else
  609.     Set rsClone = rrsRecSet.Clone()
  610.     If Not rsClone.EOF Then rsClone.MoveLast
  611.     GetNumbRecs = rsClone.RecordCount
  612.     rsClone.Close
  613.   End If
  614.  
  615.   Exit Function
  616.  
  617. GNRErr:
  618.   'just return because row count is non critical
  619.   GetNumbRecs = -1
  620.   Exit Function
  621.  
  622. End Function
  623.  
  624.  
  625. '------------------------------------------------------------
  626. 'this sub hides the menus and toolbar that only apply
  627. 'when a database is open
  628. '------------------------------------------------------------
  629. Sub HideDBTools()
  630.   frmMDI.mnuDBProperties.Visible = False
  631.   frmMDI.mnuDBClose.Visible = False
  632.   frmMDI.mnuJet.Visible = False
  633.   frmMDI.mnuUtil.Visible = False
  634. End Sub
  635.  
  636. '------------------------------------------------------------
  637. 'this sub displays the passed in message in the status
  638. 'bar on the bottom of the MDI form
  639. '------------------------------------------------------------
  640. Sub MsgBar(rsMsg As String, rPauseFlag As Integer)
  641.   If Len(rsMsg) = 0 Then
  642.     frmMDI.txtStatusMsg.Text = "Ready"
  643.   Else
  644.     If rPauseFlag = True Then
  645.       frmMDI.txtStatusMsg.Text = rsMsg & ", please wait..."
  646.     Else
  647.       frmMDI.txtStatusMsg.Text = rsMsg
  648.     End If
  649.   End If
  650.   frmMDI.txtStatusMsg.Refresh
  651. End Sub
  652.  
  653. '------------------------------------------------------------
  654. 'this sub refreshs any table list passed in as an object
  655. '------------------------------------------------------------
  656. Sub RefreshTables(rListObject As Object, rIncludeQueries As Integer)
  657.   On Error GoTo TRefErr
  658.  
  659.   Dim tdf As TableDef
  660.   Dim qdf As QueryDef
  661.   Dim sTmp As String
  662.     
  663.   Dim i As Integer
  664.     
  665.   MsgBar "Refreshing Table List", True
  666.   SetHourglass
  667.  
  668.   rListObject.Clear
  669.   If frmMDI.mnuPAllowSys.Checked = True Then
  670.     'list all tables
  671.     For Each tdf In gdbCurrentDB.TableDefs
  672.       If (tdf.Attributes And dbAttachedTable) = dbAttachedTable Then
  673.         If Left(tdf.Connect, 1) = ";" Then
  674.           'must be a jet attached table
  675.           rListObject.AddItem tdf.Name & " -> Jet"
  676.         Else
  677.           'must be an ISAM attached table
  678.           rListObject.AddItem tdf.Name & " -> " & Left(tdf.Connect, InStr(tdf.Connect, ";") - 1)
  679.         End If
  680.       ElseIf (tdf.Attributes And dbAttachedODBC) = dbAttachedODBC Then
  681.         rListObject.AddItem tdf.Name & " -> ODBC"
  682.       Else
  683.         rListObject.AddItem tdf.Name
  684.       End If
  685.     Next
  686.   Else
  687.     'don't list system tables
  688.     For Each tdf In gdbCurrentDB.TableDefs
  689.       If (tdf.Attributes And dbSystemObject) = 0 Then
  690.         If (tdf.Attributes And dbAttachedTable) = dbAttachedTable Then
  691.           If Left(tdf.Connect, 1) = ";" Then
  692.             'must be a jet attached table
  693.             rListObject.AddItem tdf.Name & " -> Jet"
  694.           Else
  695.             'must be an ISAM attached table
  696.             rListObject.AddItem tdf.Name & " -> " & Left(tdf.Connect, InStr(tdf.Connect, ";") - 1)
  697.           End If
  698.         ElseIf (tdf.Attributes And dbAttachedODBC) = dbAttachedODBC Then
  699.           rListObject.AddItem tdf.Name & " -> ODBC"
  700.         Else
  701.           rListObject.AddItem tdf.Name
  702.         End If
  703.       End If
  704.     Next
  705.   End If
  706.   'select the 1st item if there is any
  707.   If rListObject.ListCount > 0 Then
  708.     rListObject.ListIndex = 0
  709.   End If
  710.   
  711.   If rIncludeQueries Then
  712.     If gdbCurrentDB.QueryDefs.Count > 0 Then
  713.       ListItemNames gdbCurrentDB.QueryDefs, frmTables.lstQueryDefs, True
  714.     End If
  715.     'select the 1st item if there is any
  716.     If frmTables.lstQueryDefs.ListCount > 0 Then
  717.       frmTables.lstQueryDefs.ListIndex = 0
  718.     End If
  719.   End If
  720.   
  721.   Screen.MousePointer = vbDefault
  722.   MsgBar gsNULL_STR, False
  723.   Exit Sub
  724.  
  725. TRefErr:
  726.   ShowError
  727.   Exit Sub
  728.  
  729. End Sub
  730.  
  731. '------------------------------------------------------------
  732. 'this function returns the size of the field type
  733. 'passed in for use on the frmAddField form
  734. '------------------------------------------------------------
  735. Function SetFldProperties(rnType As Integer) As Integer
  736.   'return field length
  737.   Select Case rnType
  738.     Case dbBoolean
  739.       SetFldProperties = 1
  740.     Case dbByte
  741.       SetFldProperties = 1
  742.     Case dbInteger
  743.       SetFldProperties = 2
  744.     Case dbLong
  745.       SetFldProperties = 4
  746.     Case dbCurrency
  747.       SetFldProperties = 8
  748.     Case dbSingle
  749.       SetFldProperties = 4
  750.     Case dbDouble
  751.       SetFldProperties = 8
  752.     Case dbDate
  753.       SetFldProperties = 8
  754.     Case dbText
  755.       SetFldProperties = 50
  756.     Case dbLongBinary
  757.       SetFldProperties = 0
  758.     Case dbMemo
  759.       SetFldProperties = 0
  760.   End Select
  761. End Function
  762.  
  763. '------------------------------------------------------------
  764. 'this sub sets the HourGlass icon for the mouse
  765. '------------------------------------------------------------
  766. Sub SetHourglass()
  767.   DoEvents  'cause forms to repaint before going on
  768.   Screen.MousePointer = vbHourglass
  769. End Sub
  770.  
  771. '------------------------------------------------------------
  772. 'this sub shows the menus and toolbar that only apply
  773. 'when a database is open
  774. '------------------------------------------------------------
  775. Sub ShowDBTools()
  776.   frmMDI.mnuDBProperties.Visible = True
  777.   frmMDI.mnuDBClose.Visible = True
  778.   frmMDI.mnuUtil.Visible = True
  779.  
  780.   'set general items that apply/don't apply to MDBs
  781.   If gsDataType = gsJETMDB Then
  782.     frmMDI.mnuJet.Visible = True
  783.     frmSQL.cmdSaveQueryDef.Visible = True
  784.     frmTables.optTables.Visible = True
  785.     frmTables.optQueryDefs.Visible = True
  786.     frmTables.Caption = "Tables/Queries"
  787.     frmMDI.mnuPURename.Visible = True
  788.   Else
  789.     frmMDI.mnuJet.Visible = False
  790.     frmSQL.cmdSaveQueryDef.Visible = False
  791.     frmTables.optTables.Visible = False
  792.     frmTables.optQueryDefs.Visible = False
  793.     frmTables.optTables.Value = True
  794.     frmTables.Caption = "Tables"
  795.     frmMDI.mnuPURename.Visible = False
  796.   End If
  797.  
  798.   'set ODBC specific items
  799.   If gsDataType = gsSQLDB Then
  800.     frmMDI.optPassThru.Visible = True
  801.     frmMDI.optTable.Visible = False
  802.     If frmMDI.optTable.Value = True Then
  803.       frmMDI.optDynaset.Value = True
  804.     End If
  805.   Else
  806.     frmMDI.optPassThru.Visible = False
  807.     frmMDI.optTable.Visible = True
  808.     If frmMDI.optPassThru.Value = True Then
  809.       frmMDI.optDynaset.Value = True
  810.     End If
  811.   End If
  812.  
  813.   'activate the Pack menu item for xbase dbs
  814.   If gsDataType = gsDBASEIII Or gsDataType = gsDBASEIV Or gsDataType = gsFOXPRO20 Or gsDataType = gsFOXPRO25 Or gsDataType = gsFOXPRO26 Then
  815.     frmMDI.mnuPUPack.Visible = True
  816.   Else
  817.     frmMDI.mnuPUPack.Visible = False
  818.   End If
  819.  
  820. End Sub
  821.  
  822. '------------------------------------------------------------
  823. 'this sub displays the error message with it's Err code
  824. 'and prompts to show the Errors collection if it
  825. 'is a data access type error
  826. '------------------------------------------------------------
  827. Sub ShowError()
  828.   Dim sTmp As String
  829.  
  830.   Screen.MousePointer = vbDefault
  831.   MsgBar gsNULL_STR, False
  832.  
  833.   sTmp = "The following Error occurred:" & gsNewLine & gsNewLine
  834.   'add the error string
  835.   sTmp = sTmp & Error & gsNewLine
  836.   'add the error number
  837.   sTmp = sTmp & "Number: " & Err
  838.   
  839.   Beep
  840.   'check to see if the error is from the db errors collection
  841.   If DBEngine.Errors.Count > 0 Then
  842.     If DBEngine.Errors(0).Number = Err Then
  843.       'add the prompt to display the errors collection
  844.       sTmp = sTmp & gsNewLine & gsNewLine & "Display the Data Access Errors Collection?"
  845.       'beep and show the error
  846.       If MsgBox(sTmp, gnMSGBOX_TYPE) = gnMSGBOX_YES Then
  847.         RefreshErrors
  848.       End If
  849.     Else
  850.       MsgBox sTmp
  851.     End If
  852.   Else
  853.     MsgBox sTmp
  854.   End If
  855.  
  856. End Sub
  857.  
  858. '------------------------------------------------------------
  859. 'this function strips the attached table connect string off
  860. '------------------------------------------------------------
  861. Function StripConnect(rsTblName As String) As String
  862.   If InStr(rsTblName, "->") > 0 Then
  863.     StripConnect = Left(rsTblName, InStr(rsTblName, "->") - 2)
  864.   Else
  865.     StripConnect = rsTblName
  866.   End If
  867.  
  868. End Function
  869.  
  870. '------------------------------------------------------------
  871. 'this function strips the [] off of data objects
  872. '------------------------------------------------------------
  873. Function StripBrackets(rsObjName As String) As String
  874.   'add brackets to object names w/ spaces in them
  875.   If Mid(rsObjName, 1, 1) = "[" Then
  876.     StripBrackets = Mid(rsObjName, 2, Len(rsObjName) - 2)
  877.   Else
  878.     StripBrackets = rsObjName
  879.   End If
  880.  
  881. End Function
  882.  
  883. '------------------------------------------------------------
  884. 'this function strips the file name from a path\file string
  885. '------------------------------------------------------------
  886. Function StripFileName(rsFileName As String) As String
  887.   On Error Resume Next
  888.   Dim i As Integer
  889.  
  890.   For i = Len(rsFileName) To 1 Step -1
  891.     If Mid(rsFileName, i, 1) = "\" Then
  892.       Exit For
  893.     End If
  894.   Next
  895.  
  896.   StripFileName = Mid(rsFileName, 1, i - 1)
  897.  
  898. End Function
  899.  
  900. '------------------------------------------------------------
  901. 'this function strips the non ACSII chars off memo field
  902. 'data before displaying it (not sure this is always needed)
  903. '------------------------------------------------------------
  904. Function StripNonAscii(rvntVal As Variant) As String
  905.   Dim i As Integer
  906.   Dim sTmp As String
  907.  
  908.   For i = 1 To Len(rvntVal)
  909.     If Asc(Mid(rvntVal, i, 1)) < 32 Or Asc(Mid(rvntVal, i, 1)) > 126 Then
  910.       sTmp = sTmp & " "
  911.     Else
  912.       sTmp = sTmp & Mid(rvntVal, i, 1)
  913.     End If
  914.   Next
  915.  
  916.   StripNonAscii = sTmp
  917.  
  918. End Function
  919.  
  920. '------------------------------------------------------------
  921. 'strips the owner off of ODBC table names
  922. '------------------------------------------------------------
  923. Function StripOwner(rsTblName As String) As String
  924.  
  925.   If InStr(rsTblName, ".") > 0 Then
  926.     rsTblName = Mid(rsTblName, InStr(rsTblName, ".") + 1, Len(rsTblName))
  927.   End If
  928.   StripOwner = rsTblName
  929.  
  930. End Function
  931.  
  932. '------------------------------------------------------------
  933. 'returns the true or false string
  934. '------------------------------------------------------------
  935. Function stTrueFalse(rvntTF As Variant) As String
  936.   If rvntTF = True Then
  937.     stTrueFalse = "True"
  938.   Else
  939.     stTrueFalse = "False"
  940.   End If
  941. End Function
  942.  
  943. '------------------------------------------------------------
  944. 'returns "" if a field is Null
  945. '------------------------------------------------------------
  946. Function vFieldVal(rvntFieldVal As Variant) As Variant
  947.   If IsNull(rvntFieldVal) Then
  948.     vFieldVal = gsNULL_STR
  949.   Else
  950.     vFieldVal = CStr(rvntFieldVal)
  951.   End If
  952. End Function
  953.  
  954. '------------------------------------------------------------
  955. 'loads all saved INI settings for VisData
  956. '------------------------------------------------------------
  957. Sub LoadINISettings()
  958.   On Error Resume Next
  959.   
  960.   Dim sTmp As String
  961.   Dim x As Integer
  962.  
  963.   glQueryTimeout = Val(GetINIString("QueryTimeout", "5", gsVISDATA4))
  964.   glLoginTimeout = Val(GetINIString("LoginTimeout", "20", gsVISDATA4))
  965.   
  966.   sTmp = GetINIString("ViewMode", CStr(gnNODATACTL_FORM), gsVISDATA4)
  967.   Select Case Val(sTmp)
  968.     Case gnNODATACTL_FORM
  969.       frmMDI.optNoDataCtl.Value = True
  970.     Case gnDATACTL_FORM
  971.      frmMDI.optDataCtl.Value = True
  972.     Case gnDATAGRID_FORM
  973.       frmMDI.optDataGrid.Value = True
  974.   End Select
  975.   sTmp = GetINIString("RecordsetType", CStr(vbRSTypeDynaset), gsVISDATA4)
  976.   Select Case Val(sTmp)
  977.     Case vbRSTypeDynaset
  978.       frmMDI.optDynaset.Value = True
  979.     Case vbRSTypeSnapShot
  980.       frmMDI.optSnapshot.Value = True
  981.     Case vbRSTypeTable
  982.       frmMDI.optTable.Value = True
  983.     Case gnRS_PASSTHRU
  984.       frmMDI.optPassThru.Value = True
  985.   End Select
  986.   
  987.   frmMDI.mnuPOpenOnStartup.Checked = Val(GetINIString("OpenOnStartup", "0", gsVISDATA4))
  988.   frmMDI.mnuPShowPerf.Checked = Val(GetINIString("ShowPerf", "0", gsVISDATA4))
  989.   frmMDI.mnuPAllowSys.Checked = Val(GetINIString("AllowSys", "0", gsVISDATA4))
  990.  
  991.   'get the most recently used databases
  992.   For x = 1 To 4
  993.     sTmp = GetINIString("MRUDatabase" & x, "", gsVISDATA4)
  994.     If Len(sTmp) > 0 Then
  995.       frmMDI.mnuBarMRU.Visible = True
  996.       frmMDI.mnuDBMRU(x).Caption = "&" & x & " " & sTmp
  997.       frmMDI.mnuDBMRU(x).Visible = True
  998.       sTmp = GetINIString("MRUConnect" & x, "", gsVISDATA4)
  999.       frmMDI.mnuDBMRU(x).Tag = sTmp
  1000.     End If
  1001.   Next
  1002.  
  1003.   'get the last used database out of the INI file
  1004.   gsDataType = GetINIString("DataType", gsNULL_STR, gsVISDATA4)
  1005.   gsDBName = GetINIString("DatabaseName", gsNULL_STR, gsVISDATA4)
  1006.   gsODBCDatasource = GetINIString("ODBCDatasource", gsNULL_STR, gsVISDATA4)
  1007.   gsODBCDatabase = GetINIString("ODBCDatabase", gsNULL_STR, gsVISDATA4)
  1008.   gsODBCUserName = GetINIString("ODBCUserName", gsNULL_STR, gsVISDATA4)
  1009.   gsODBCPassword = GetINIString("ODBCPassword", gsNULL_STR, gsVISDATA4)
  1010.  
  1011.   x = Val(GetINIString("WindowState", "2", gsVISDATA4))
  1012.   If x <> 1 Then
  1013.     frmMDI.WindowState = x
  1014.   Else
  1015.     frmMDI.WindowState = 0
  1016.   End If
  1017.   If frmMDI.WindowState = 0 Then
  1018.     frmMDI.Left = Val(GetINIString("WindowLeft", "0", gsVISDATA4))
  1019.     frmMDI.Top = Val(GetINIString("WindowTop", "0", gsVISDATA4))
  1020.     frmMDI.Width = Val(GetINIString("WindowWidth", "9135", gsVISDATA4))
  1021.     frmMDI.Height = Val(GetINIString("WindowHeight", "6900", gsVISDATA4))
  1022.   End If
  1023.   
  1024. End Sub
  1025.  
  1026. '------------------------------------------------------------
  1027. 'saves current VisData values in VISDATA.INI
  1028. '------------------------------------------------------------
  1029. Sub SaveINISettings()
  1030.   On Error Resume Next
  1031.  
  1032.   Dim i As Integer
  1033.   
  1034.   SaveSetting "VisData", gsVISDATA4, "DataType", gsDataType
  1035.   SaveSetting "VisData", gsVISDATA4, "DatabaseName", gsDBName
  1036.   SaveSetting "VisData", gsVISDATA4, "ODBCDatasource", gsODBCDatasource
  1037.   SaveSetting "VisData", gsVISDATA4, "ODBCDatabase", gsODBCDatabase
  1038.   SaveSetting "VisData", gsVISDATA4, "ODBCUserName", gsODBCUserName
  1039.   SaveSetting "VisData", gsVISDATA4, "ODBCPassword", gsODBCPassword
  1040.   SaveSetting "VisData", gsVISDATA4, "QueryTimeout", glQueryTimeout
  1041.   SaveSetting "VisData", gsVISDATA4, "LoginTimeout", glLoginTimeout
  1042.   DBEngine.LoginTimeout = glLoginTimeout
  1043.   SaveSetting "VisData", gsVISDATA4, "ViewMode", gnFormType
  1044.   SaveSetting "VisData", gsVISDATA4, "RecordsetType", gnRecordsetType
  1045.   
  1046.   SaveSetting "VisData", gsVISDATA4, "OpenOnStartup", IIf(frmMDI.mnuPOpenOnStartup.Checked, "-1", "0")
  1047.   SaveSetting "VisData", gsVISDATA4, "ShowPerf", IIf(frmMDI.mnuPShowPerf.Checked, "-1", "0")
  1048.   SaveSetting "VisData", gsVISDATA4, "AllowSys", IIf(frmMDI.mnuPAllowSys.Checked, "-1", "0")
  1049.  
  1050.   For i = 1 To 4
  1051.     If frmMDI.mnuDBMRU(i).Visible Then
  1052.       SaveSetting "VisData", gsVISDATA4, "MRUDatabase" & i, Mid(frmMDI.mnuDBMRU(i).Caption, 4, Len(frmMDI.mnuDBMRU(i).Caption))
  1053.       SaveSetting "VisData", gsVISDATA4, "MRUConnect" & i, frmMDI.mnuDBMRU(i).Tag
  1054.     Else
  1055.       SaveSetting "VisData", gsVISDATA4, "MRUDatabase" & i, ""
  1056.       SaveSetting "VisData", gsVISDATA4, "MRUConnect" & i, ""
  1057.     End If
  1058.   Next
  1059.  
  1060.   SaveSetting "VisData", gsVISDATA4, "WindowState", frmMDI.WindowState
  1061.   If frmMDI.WindowState = vbNormal Then
  1062.     SaveSetting "VisData", gsVISDATA4, "WindowTop", frmMDI.Top
  1063.     SaveSetting "VisData", gsVISDATA4, "WindowLeft", frmMDI.Left
  1064.     SaveSetting "VisData", gsVISDATA4, "WindowWidth", frmMDI.Width
  1065.     SaveSetting "VisData", gsVISDATA4, "WindowHeight", frmMDI.Height
  1066.   End If
  1067.  
  1068.   'only save the sql text if there are no carriage returns in it
  1069.   'because they are not preserved in the INI file
  1070.   If InStr(frmSQL.txtSQLStatement.Text, Chr(13)) = 0 Then
  1071.     SaveSetting "VisData", gsVISDATA4, "SQLStatement", frmSQL.txtSQLStatement.Text
  1072.   End If
  1073.   If frmSQL.WindowState = vbNormal Then
  1074.     SaveSetting "VisData", gsVISDATA4, "SQLWindowTop", frmSQL.Top
  1075.     SaveSetting "VisData", gsVISDATA4, "SQLWindowLeft", frmSQL.Left
  1076.     SaveSetting "VisData", gsVISDATA4, "SQLWindowWidth", frmSQL.Width
  1077.     SaveSetting "VisData", gsVISDATA4, "SQLWindowHeight", frmSQL.Height
  1078.   End If
  1079.   If frmTables.WindowState = vbNormal Then
  1080.     SaveSetting "VisData", gsVISDATA4, "TBLWindowTop", frmTables.Top
  1081.     SaveSetting "VisData", gsVISDATA4, "TBLWindowLeft", frmTables.Left
  1082.     SaveSetting "VisData", gsVISDATA4, "TBLWindowWidth", frmTables.Width
  1083.     SaveSetting "VisData", gsVISDATA4, "TBLWindowHeight", frmTables.Height
  1084.   End If
  1085. End Sub
  1086.  
  1087. '------------------------------------------------------------
  1088. 'this sub will open the appropriate data type form and
  1089. 'display the appropriate msg in the status bar based on
  1090. 'user selected options on the main MDI form
  1091. '------------------------------------------------------------
  1092. Sub OpenTable(rName As String)
  1093.   Dim sTmp As String
  1094.   Dim nAttach As Integer
  1095.   
  1096.   If gsDataType = gsJETMDB Then   'look for attached tables if it's an MDB
  1097.     If (gdbCurrentDB.TableDefs(rName).Attributes And dbAttachedTable) = dbAttachedTable Then
  1098.       nAttach = 1
  1099.     ElseIf (gdbCurrentDB.TableDefs(rName).Attributes And dbAttachedODBC) = dbAttachedODBC Then
  1100.       nAttach = 2
  1101.     End If
  1102.     If nAttach > 0 And frmMDI.optTable.Value = True Then
  1103.       Beep
  1104.       If MsgBox("Can't do OpenTable on an Attached Table, Use Dynaset?", gnMSGBOX_TYPE) = gnMSGBOX_YES Then
  1105.         frmMDI.optDynaset.Value = True         'reset to recordset
  1106.       Else
  1107.         Exit Sub
  1108.       End If
  1109.     End If
  1110.   End If
  1111.   
  1112.   sTmp = "Opening "
  1113.  
  1114.   If frmMDI.optTable.Value = True Then
  1115.     sTmp = sTmp & "Full Table "
  1116.   ElseIf frmMDI.optDynaset.Value = True Then
  1117.     sTmp = sTmp & "Single Table Dynaset "
  1118.   ElseIf frmMDI.optSnapshot.Value = True Then
  1119.     sTmp = sTmp & "Single Table Snapshot "
  1120.   ElseIf frmMDI.optPassThru.Value = True Then
  1121.     sTmp = sTmp & "PassThru Snapshot "
  1122.   End If
  1123.   
  1124.   If nAttach = 1 Then
  1125.     sTmp = sTmp & " on Attached Table"
  1126.   ElseIf nAttach = 2 Then
  1127.     sTmp = sTmp & " on Attached ODBC Table"
  1128.   End If
  1129.   
  1130.   MsgBar sTmp, True
  1131.   
  1132.   If frmMDI.optNoDataCtl.Value = True Then
  1133.     If frmMDI.optTable.Value = True Then
  1134.       Dim frmTBL As New frmTableObj
  1135.       frmTBL.Show
  1136.     Else
  1137.       Dim frmDS As New frmDynaSnap
  1138.       frmDS.Show
  1139.     End If
  1140.   ElseIf frmMDI.optDataCtl.Value = True Then
  1141.     Dim frmDC As New frmDataControl
  1142.     frmDC.Show
  1143.   ElseIf frmMDI.optDataGrid.Value = True Then
  1144.     Dim frmDG As New frmDataGrid
  1145.     frmDG.Show
  1146.   End If
  1147.  
  1148. End Sub
  1149.  
  1150. '------------------------------------------------------------
  1151. 'opens a QueryDef with the user selected form type
  1152. '------------------------------------------------------------
  1153. Sub OpenQuery(rName As String)
  1154.   Dim qd As QueryDef
  1155.   Dim sQueryType As String
  1156.  
  1157.   sQueryType = ActionQueryType()
  1158.   Set qd = gdbCurrentDB.QueryDefs(frmTables.lstQueryDefs.Text)
  1159.   If qd.ReturnsRecords = True And frmMDI.optTable.Value = True Then
  1160.     Beep
  1161.     If MsgBox("Can't do OpenTable on a QueryDef, Use Dynaset?", gnMSGBOX_TYPE) = gnMSGBOX_YES Then
  1162.       frmMDI.optDynaset.Value = True         'reset to recordset
  1163.     Else
  1164.       Exit Sub
  1165.     End If
  1166.   End If
  1167.   
  1168.   gsDynaString = qd.SQL
  1169.   
  1170.   If qd.ReturnsRecords = True Then
  1171.     If qd.Type = dbQSQLPassThrough Or frmMDI.optSnapshot.Value = True Then
  1172.       MsgBar "Opening Query Snapshot", True
  1173.     Else
  1174.       MsgBar "Opening Query Dynaset", True
  1175.     End If
  1176.     If frmMDI.optNoDataCtl = True Then
  1177.       Dim frmDS As New frmDynaSnap
  1178.       frmDS.Show
  1179.     ElseIf frmMDI.optDataCtl.Value = True Then
  1180.       Dim frmDC As New frmDataControl
  1181.       frmDC.Show
  1182.     ElseIf frmMDI.optDataGrid.Value = True Then
  1183.       Dim frmDG As New frmDataGrid
  1184.       frmDG.Show
  1185.     End If
  1186.   Else
  1187.     Screen.MousePointer = vbDefault
  1188.     If MsgBox("Run " & sQueryType & " Query?", gnMSGBOX_TYPE) = gnMSGBOX_YES Then
  1189.       SetHourglass
  1190.       MsgBar "Executing " & sQueryType & " Query", True
  1191.       qd.Execute
  1192.     End If
  1193.   End If
  1194. End Sub
  1195.  
  1196. '------------------------------------------------------------
  1197. 'this sub displays properties for the passed in object
  1198. '------------------------------------------------------------
  1199. Sub ShowProperties(rName As String, rObj As Object)
  1200.   On Error GoTo SPErr
  1201.   
  1202.   Dim frm As New frmPropertySheet
  1203.   
  1204.   SetHourglass
  1205.   Set gPropObject = rObj
  1206.   frm.Caption = rName & " Properties"
  1207.   frm.Show
  1208.     
  1209.   Exit Sub
  1210.   
  1211. SPErr:
  1212.   ShowError
  1213.   Exit Sub
  1214.   
  1215. End Sub
  1216.  
  1217. '------------------------------------------------------------
  1218. 'this function sets the list to the correct item
  1219. 'after the right mouse button was clicked
  1220. '------------------------------------------------------------
  1221. Function SetPropItem(rLst As Object, rY As Single) As Integer
  1222.   On Error GoTo SPIErr
  1223.   
  1224.   Dim i As Integer
  1225.   
  1226.   If rLst.ListCount = 0 Then
  1227.     SetPropItem = False
  1228.     Exit Function
  1229.   End If
  1230.   
  1231.   'get the item height
  1232.   i = rLst.Parent.TextHeight(rLst.List(0))
  1233.   'get the item from the Y coordinate
  1234.   i = rY \ i
  1235.   'check for it off the bottom
  1236.   If i + rLst.TopIndex > rLst.ListCount - 1 Then
  1237.     SetPropItem = False
  1238.     Exit Function
  1239.   End If
  1240.   'set the index
  1241.   rLst.ListIndex = i + rLst.TopIndex
  1242.   
  1243.   SetPropItem = True
  1244.   Exit Function
  1245.   
  1246. SPIErr:
  1247.   SetPropItem = False
  1248.   Exit Function
  1249.   
  1250. End Function
  1251.  
  1252. '------------------------------------------------------------
  1253. 'this sub closes all object property forms
  1254. '------------------------------------------------------------
  1255. Sub CloseAllPropForms()
  1256.   Dim i As Integer
  1257.  
  1258.   MsgBar "Closing Property Forms", True
  1259.   While i < Forms.Count
  1260.     If Forms(i).Tag = "Properties" Then
  1261.       Unload Forms(i)
  1262.     Else
  1263.       i = i + 1
  1264.     End If
  1265.   Wend
  1266.   MsgBar gsNULL_STR, False
  1267. End Sub
  1268.  
  1269. '------------------------------------------------------------
  1270. 'this sub display all field data in the current row
  1271. 'on the table and dynasnap forms
  1272. '------------------------------------------------------------
  1273. Sub DisplayCurrentRecord(frm As Object, rec As Recordset, lCnt As Long, bNew As Integer)
  1274.   Dim i As Integer
  1275.   Dim sCurrStat As String
  1276.   Dim lCurrRec As Long
  1277.   Dim bNoInd As Integer
  1278.  
  1279.   On Error GoTo DCRErr
  1280.  
  1281.   SetHourglass
  1282.  
  1283.   sCurrStat = "Row "
  1284.    
  1285.   'check to see if a table w/ 0 indexes is in use
  1286.   If rec.Type = dbOpenTable Then
  1287.     If gdbCurrentDB(rec.Name).Indexes.Count = 0 Then
  1288.       bNoInd = True
  1289.     End If
  1290.   End If
  1291.    
  1292.   'check for an empty recordset
  1293.   If rec.RecordCount > 0 Then
  1294.     lCurrRec = (lCnt * (rec.PercentPosition * 0.01)) + 1
  1295.   End If
  1296.      
  1297.   'check BOF/EOF flag so we know if we
  1298.   'are sitting on a valid record
  1299.   If bNew = True Then
  1300.     If bNoInd = True Then
  1301.       sCurrStat = lCnt & " Rows"
  1302.     Else
  1303.       sCurrStat = sCurrStat & lCurrRec & " of " & lCnt
  1304.     End If
  1305.   Else
  1306.     If rec.BOF = True Then
  1307.       sCurrStat = sCurrStat & "(BOF) of " & lCnt
  1308.       ClearDataFields frm, rec.Fields.Count
  1309.     ElseIf rec.EOF = True Then
  1310.       sCurrStat = sCurrStat & "(EOF) of " & lCnt
  1311.       ClearDataFields frm, rec.Fields.Count
  1312.     Else
  1313.       If bNoInd = True Then
  1314.         sCurrStat = lCnt & " Rows"
  1315.       Else
  1316.         sCurrStat = sCurrStat & lCurrRec & " of " & lCnt
  1317.       End If
  1318.       'place the data in the form fields
  1319.       For i = 0 To rec.Fields.Count - 1
  1320.         If rec(i).Type = dbMemo Then
  1321.           If rec(i).FieldSize() < gnGETCHUNK_CUTOFF Then
  1322.             frm.txtFieldData(i).Text = StripNonAscii(vFieldVal(rec(i)))
  1323.           Else
  1324.             frm.txtFieldData(i).Text = StripNonAscii(vFieldVal(rec(i).GetChunk(0, gnGETCHUNK_CUTOFF)))
  1325.           End If
  1326.         ElseIf rec(i).Type = dbText Then
  1327.           frm.txtFieldData(i).Text = StripNonAscii(vFieldVal(rec(i)))
  1328.         Else
  1329.           frm.txtFieldData(i).Text = vFieldVal(rec(i))
  1330.         End If
  1331.       Next
  1332.     End If
  1333.   End If
  1334.   If rec.Updatable = False Then sCurrStat = sCurrStat & "  [Not Updatable]"
  1335.   frm.lblStatus.Caption = sCurrStat
  1336.   Screen.MousePointer = vbDefault
  1337.   Exit Sub
  1338.  
  1339. DCRErr:
  1340.   ShowError
  1341.   Resume Next    'so we can try and display as much data as possible
  1342.   Exit Sub
  1343.  
  1344. End Sub
  1345.  
  1346. '------------------------------------------------------------
  1347. 'this function checks to see if the passed in name exists
  1348. 'in either the Tabledefs or Querydefs collection
  1349. 'it found, it prompts to delete it and returns false
  1350. 'if the user selects to delete it or true if not
  1351. 'if not found, it returns false
  1352. '------------------------------------------------------------
  1353. Function DupeTableName(rName As String) As Integer
  1354.   On Error GoTo DTNErr
  1355.  
  1356.   Dim tdf As TableDef
  1357.   Dim qdf As QueryDef
  1358.   Dim i As Integer
  1359.  
  1360.   For Each tdf In gdbCurrentDB.TableDefs
  1361.     If UCase(tdf.Name) = UCase(rName) Then
  1362.       If MsgBox("Table '" & rName & "' exists, Delete it?", gnMSGBOX_TYPE) = gnMSGBOX_YES Then
  1363.         gdbCurrentDB.TableDefs.Delete rName
  1364.         DupeTableName = False
  1365.       Else
  1366.         DupeTableName = True
  1367.       End If
  1368.       Exit Function
  1369.     End If
  1370.   Next
  1371.  
  1372.   If gsDataType = gsJETMDB Then
  1373.     For Each qdf In gdbCurrentDB.QueryDefs
  1374.       If UCase(qdf.Name) = UCase(rName) Then
  1375.         If MsgBox("QueryDef '" & rName & "' exists, Delete it?", gnMSGBOX_TYPE) = gnMSGBOX_YES Then
  1376.           gdbCurrentDB.QueryDefs.Delete rName
  1377.           DupeTableName = False
  1378.         Else
  1379.           DupeTableName = True
  1380.         End If
  1381.         Exit Function
  1382.       End If
  1383.     Next
  1384.   End If
  1385.  
  1386.   DupeTableName = False
  1387.   Exit Function
  1388.  
  1389. DTNErr:
  1390.   ShowError
  1391.   DupeTableName = False
  1392.   Exit Function
  1393.  
  1394. End Function
  1395.  
  1396. '------------------------------------------------------------
  1397. 'this sub unloads all forms except for the
  1398. 'SQL, Tables and MDI form
  1399. '------------------------------------------------------------
  1400. Sub UnloadAllForms()
  1401.   On Error Resume Next
  1402.   
  1403.   Dim i As Integer
  1404.   
  1405.   'close all forms except for the Tables and SQL forms
  1406.   For i = Forms.Count - 1 To 3 Step -1
  1407.     Unload Forms(i)
  1408.   Next
  1409. End Sub
  1410.  
  1411. '------------------------------------------------------------
  1412. 'this sub walks the parameters collection in a parameterized
  1413. 'query and prompts the user for a value for each parameter
  1414. '------------------------------------------------------------
  1415. Sub SetParams(rqdf As QueryDef)
  1416.   On Error GoTo SPErr
  1417.   
  1418.   Dim prm As Parameter
  1419.   Dim sTmp As String
  1420.   Dim i As Integer
  1421.   
  1422.   For Each prm In rqdf.Parameters
  1423.     'get the value from the user
  1424.     sTmp = InputBox("Enter Value for Parameter '" & prm.Name & "':")
  1425.     'store the value
  1426.     prm.Value = CVar(sTmp)
  1427.   Next
  1428.   
  1429.   Exit Sub
  1430.     
  1431. SPErr:
  1432.   ShowError
  1433.   Exit Sub
  1434. End Sub
  1435.  
  1436. '------------------------------------------------------------
  1437. 'this sub refreshs the Error form with the latest Errors
  1438. '------------------------------------------------------------
  1439. Sub RefreshErrors()
  1440.   On Error GoTo RErr
  1441.   
  1442.   Dim errObj As Error
  1443.   Dim i As Integer
  1444.  
  1445.   If DBEngine.Errors.Count = 0 Then
  1446.     MsgBox "There are no current data access errors!", 48
  1447.     Unload frmErrors
  1448.     Exit Sub
  1449.   End If
  1450.  
  1451.   frmErrors.Show
  1452.   frmErrors.grdErrors.Rows = DBEngine.Errors.Count + 1
  1453.   For i = 0 To DBEngine.Errors.Count - 1
  1454.     Set errObj = DBEngine.Errors(i)
  1455.     frmErrors.grdErrors.Row = i + 1
  1456.     frmErrors.grdErrors.Col = 0
  1457.     frmErrors.grdErrors.Text = errObj.Number
  1458.     frmErrors.grdErrors.Col = 1
  1459.     frmErrors.grdErrors.Text = errObj.Source
  1460.     frmErrors.grdErrors.Col = 2
  1461.     frmErrors.grdErrors.Text = errObj.Description
  1462.   Next
  1463.   frmErrors.SetFocus
  1464.  
  1465.   Exit Sub
  1466.   
  1467. RErr:
  1468.   MsgBox "Can't show Errors at this time!", 48
  1469.   Unload frmErrors
  1470.   Exit Sub
  1471. End Sub
  1472.  
  1473. '------------------------------------------------------------
  1474. 'this sub adds the just opened database to the most recently
  1475. 'used list in the File menu
  1476. '------------------------------------------------------------
  1477. Sub AddMRU()
  1478.   On Error GoTo AMErr
  1479.  
  1480.   Dim i As Integer, j As Integer
  1481.  
  1482.   '1st look to see if it alread exists and swap it if it does
  1483.   For i = 1 To 4
  1484.     If UCase(Mid(frmMDI.mnuDBMRU(i).Caption, 4, Len(frmMDI.mnuDBMRU(i).Caption))) = UCase(gsDBName) Then
  1485.       For j = i To 2 Step -1
  1486.         frmMDI.mnuDBMRU(j).Caption = "&" & j & " " & Mid(frmMDI.mnuDBMRU(j - 1).Caption, 4, Len(frmMDI.mnuDBMRU(j - 1).Caption))
  1487.         frmMDI.mnuDBMRU(j).Tag = frmMDI.mnuDBMRU(j - 1).Tag
  1488.       Next
  1489.       GoTo Finish
  1490.     End If
  1491.   Next
  1492.  
  1493.   'wasn't there so move everything down one
  1494.   For i = 3 To 1 Step -1
  1495.     frmMDI.mnuDBMRU(i + 1).Caption = "&" & i + 1 & " " & Mid(frmMDI.mnuDBMRU(i).Caption, 4, Len(frmMDI.mnuDBMRU(i).Caption))
  1496.     frmMDI.mnuDBMRU(i + 1).Tag = frmMDI.mnuDBMRU(i).Tag
  1497.   Next
  1498.  
  1499. Finish:
  1500.   frmMDI.mnuDBMRU(1).Caption = "&1 " & gsDBName
  1501.   If Len(gdbCurrentDB.Connect) = 0 Then
  1502.     'handle the Access case where there is no connect string
  1503.     frmMDI.mnuDBMRU(1).Tag = gsJETMDB
  1504.   Else
  1505.     frmMDI.mnuDBMRU(1).Tag = gdbCurrentDB.Connect
  1506.   End If
  1507.   frmMDI.mnuBarMRU.Visible = True
  1508.   For i = 1 To 4
  1509.     If Len(Mid(frmMDI.mnuDBMRU(i).Caption, 4, Len(frmMDI.mnuDBMRU(i).Caption))) > 0 Then
  1510.       frmMDI.mnuDBMRU(i).Visible = True
  1511.     End If
  1512.   Next
  1513.  
  1514.   Exit Sub
  1515.  
  1516. AMErr:
  1517.   ShowError
  1518.   Exit Sub
  1519.  
  1520. End Sub
  1521.  
  1522. '------------------------------------------------------------
  1523. 'this sub breaks out the parts of a ODBC connect string
  1524. 'and assigns them to the global ODBC variables
  1525. '------------------------------------------------------------
  1526. Sub GetODBCConnectParts(rsConnect As String)
  1527.   On Error Resume Next
  1528.   
  1529.   Dim i As Integer
  1530.   Dim sTmp As String
  1531.   
  1532.   'process the connect string just in case the
  1533.   'values came from the ODBC dialogs
  1534.   If InStr(rsConnect, "=") Then
  1535.     i = 1
  1536.     While i <= Len(rsConnect) + 1
  1537.       If Mid(rsConnect, i, 1) = ";" Or i = Len(rsConnect) + 1 Then
  1538.         If Len(sTmp) > 0 And InStr(sTmp, "=") > 0 Then
  1539.           Select Case Mid(sTmp, 1, InStr(1, sTmp, "=") - 1)
  1540.             Case "DSN"
  1541.               gsODBCDatasource = Mid(sTmp, InStr(1, sTmp, "=") + 1, Len(sTmp))
  1542.             Case "DATABASE"
  1543.               gsODBCDatabase = Mid(sTmp, InStr(1, sTmp, "=") + 1, Len(sTmp))
  1544.             Case "DBQ"
  1545.               gsODBCDatabase = Mid(sTmp, InStr(1, sTmp, "=") + 1, Len(sTmp))
  1546.             Case "UID"
  1547.               gsODBCUserName = Mid(sTmp, InStr(1, sTmp, "=") + 1, Len(sTmp))
  1548.             Case "PWD"
  1549.               gsODBCPassword = Mid(sTmp, InStr(1, sTmp, "=") + 1, Len(sTmp))
  1550.              Case Else
  1551.               'nothing
  1552.           End Select
  1553.         End If
  1554.         sTmp = gsNULL_STR
  1555.       Else
  1556.         sTmp = sTmp + Mid(rsConnect, i, 1)
  1557.       End If
  1558.       i = i + 1
  1559.     Wend
  1560.   End If
  1561. End Sub
  1562.  
  1563. '------------------------------------------------------------
  1564. 'this is a generic sub that adds the name of each item
  1565. 'in a collection to the passed in control
  1566. '------------------------------------------------------------
  1567. Sub ListItemNames(rcCollection As Object, rnCtl As Control, bClearList As Integer)
  1568.   On Error GoTo LINErr
  1569.   
  1570.   Dim objTmp As Object
  1571.   Dim i As Integer
  1572.   
  1573.   If bClearList = True Then
  1574.     rnCtl.Clear
  1575.   End If
  1576.   
  1577.   For Each objTmp In rcCollection
  1578.     rnCtl.AddItem objTmp.Name
  1579.   Next
  1580.  
  1581.   Exit Sub
  1582.   
  1583. LINErr:
  1584.   ShowError
  1585.   Exit Sub
  1586. End Sub
  1587.  
  1588. '------------------------------------------------------------
  1589. 'these functions may be needed to replace the internal string
  1590. 'functions with the "B" version for 16 bit to handle
  1591. 'DBCS strings and use the standard string function for 32 bit
  1592. 'where Unicode handles the DBCS strings
  1593. '------------------------------------------------------------
  1594. 'Function Mid(sString, lStart, Optional lLength) As String
  1595. '#If Win16 Then
  1596. '    Mid = VBA.MidB(sString, lStart, lLength)
  1597. '#Else
  1598. '    Mid = VBA.Mid(sString, lStart, lLength)
  1599. '#End If
  1600. 'End Function
  1601.  
  1602. 'Function Len(sString) As Variant
  1603. '#If Win16 Then
  1604. '    Len = VBA.LenB(sString)
  1605. '#Else
  1606. '    Len = VBA.Len(sString)
  1607. '#End If
  1608. 'End Function
  1609.  
  1610. 'Function Left(sString, Optional lLength) As String
  1611. '#If Win16 Then
  1612. '    Left = VBA.LeftB(sString, lLength)
  1613. '#Else
  1614. '    Left = VBA.Left(sString, lLength)
  1615. '#End If
  1616. 'End Function
  1617.  
  1618.  
  1619. '------------------------------------------------------------
  1620. 'this sub closes the current DB and performs any cleanup
  1621. 'and resetting of controls, menus, etc.
  1622. '------------------------------------------------------------
  1623. Sub CloseCurrentDB()
  1624.   On Error GoTo DBCloseErr
  1625.  
  1626.   If gbDBChanged Then
  1627.     If MsgBox("Data has been changed, Commit it?", gnMSGBOX_TYPE) = gnMSGBOX_YES Then
  1628.       gwsMainWS.CommitTrans
  1629.       gbDBChanged = False
  1630.     Else
  1631.       If MsgBox("RollBack All changes?", gnMSGBOX_TYPE) = gnMSGBOX_YES Then
  1632.         gwsMainWS.Rollback
  1633.         gbDBChanged = False
  1634.       Else
  1635.         Beep
  1636.         MsgBox "Can't Close with Transactions Pending!", 48
  1637.         Exit Sub
  1638.       End If
  1639.     End If
  1640.   End If
  1641.  
  1642.   UnloadAllForms
  1643.   frmMDI.Caption = "VisData"
  1644.   
  1645.   frmTables.lstTables.Clear
  1646.   frmTables.lstQueryDefs.Clear
  1647.   frmTables.optTables.Visible = False
  1648.   frmTables.optQueryDefs.Visible = False
  1649.   frmTables.optTables.Value = True
  1650.  
  1651.   HideDBTools
  1652.  
  1653.   gbDBOpenFlag = False
  1654.   gbTransPending = False
  1655.   gsDBName = gsNULL_STR
  1656.   gnReadOnly = False
  1657.   
  1658.   gdbCurrentDB.Close
  1659.   Set gdbCurrentDB = Nothing
  1660.  
  1661.   Exit Sub
  1662.  
  1663. DBCloseErr:
  1664.   ShowError
  1665.   Exit Sub
  1666. End Sub
  1667.  
  1668. '------------------------------------------------------------
  1669. '------------------------------------------------------------
  1670. Sub OpenLocalDB(doit As Integer)
  1671.   On Error GoTo OpenError
  1672.  
  1673.   Dim sConnect As String
  1674.   Dim sDatabaseName As String
  1675.  
  1676.   sDatabaseName = gsDBName
  1677.   
  1678.   If gbDBOpenFlag = True Then
  1679.     CloseCurrentDB
  1680.   End If
  1681.  
  1682.   If gbDBOpenFlag = True Then
  1683.     Beep
  1684.     MsgBox "You must Close First!", 48
  1685.     Exit Sub
  1686.   Else
  1687.     If doit = False Then
  1688.       Select Case gsDataType
  1689.         Case gsJETMDB
  1690.           frmMDI.dlgCMD1.Filter = "Jet Engine MDBs (*.mdb)|*.mdb|All Files (*.*)|*.*"
  1691.           frmMDI.dlgCMD1.DialogTitle = "Open Jet Database"
  1692.         Case gsDBASEIII
  1693.           frmMDI.dlgCMD1.Filter = "Dbase III DBs (*.dbf)|*.dbf"
  1694.           frmMDI.dlgCMD1.DialogTitle = "Open Dbase III Database"
  1695.         Case gsDBASEIV
  1696.           frmMDI.dlgCMD1.Filter = "Dbase IV DBs (*.dbf)|*.dbf"
  1697.           frmMDI.dlgCMD1.DialogTitle = "Open Dbase IV Database"
  1698.         Case gsFOXPRO20
  1699.           frmMDI.dlgCMD1.Filter = "FoxPro DBs (*.dbf)|*.dbf"
  1700.           frmMDI.dlgCMD1.DialogTitle = "Open FoxPro 2.0 Database"
  1701.         Case gsFOXPRO25
  1702.           frmMDI.dlgCMD1.Filter = "FoxPro DBs (*.dbf)|*.dbf"
  1703.           frmMDI.dlgCMD1.DialogTitle = "Open FoxPro 2.5 Database"
  1704.         Case gsFOXPRO26
  1705.           frmMDI.dlgCMD1.Filter = "FoxPro DBs (*.dbf)|*.dbf"
  1706.           frmMDI.dlgCMD1.DialogTitle = "Open FoxPro 2.6 Database"
  1707.         Case gsPARADOX3X
  1708.           frmMDI.dlgCMD1.Filter = "Paradox DBs (*.db)|*.db"
  1709.           frmMDI.dlgCMD1.DialogTitle = "Open Paradox 3.X Database"
  1710.         Case gsPARADOX4X
  1711.           frmMDI.dlgCMD1.Filter = "Paradox DBs (*.db)|*.db"
  1712.           frmMDI.dlgCMD1.DialogTitle = "Open Paradox 4.X Database"
  1713.         Case gsEXCEL50
  1714.           frmMDI.dlgCMD1.Filter = "Excel Files (*.xls)|*.xls"
  1715.           frmMDI.dlgCMD1.DialogTitle = "Open Excel File"
  1716.         Case gsBTRIEVE
  1717.           frmMDI.dlgCMD1.Filter = "Btrieve DBs (FILE.DDF)|FILE.DDF"
  1718.           frmMDI.dlgCMD1.DialogTitle = "Open Btrieve Database"
  1719.         Case gsTEXTFILES
  1720.           frmMDI.dlgCMD1.Filter = "Text Files (*.txt)|*.txt|All Files (*.*)|*.*"
  1721.           frmMDI.dlgCMD1.DialogTitle = "Open Text Database"
  1722.       End Select
  1723.  
  1724.       frmMDI.dlgCMD1.FilterIndex = 1
  1725.       frmMDI.dlgCMD1.FileName = gsDBName  '""
  1726.       frmMDI.dlgCMD1.CancelError = True
  1727.       frmMDI.dlgCMD1.Flags = FileOpenConstants.cdlOFNFileMustExist
  1728.       frmMDI.dlgCMD1.ShowOpen
  1729.  
  1730.       If Len(frmMDI.dlgCMD1.FileName) > 0 Then
  1731.         gsDBName = frmMDI.dlgCMD1.FileName
  1732.       Else
  1733.         Exit Sub
  1734.       End If
  1735.     Else
  1736.       gsDBName = sDatabaseName
  1737.     End If
  1738.   End If
  1739.  
  1740.   MsgBar "Opening Database", True
  1741.   SetHourglass
  1742.  
  1743.   'set the connect string
  1744.   If gsDataType = gsJETMDB Then
  1745.     sConnect = gsNULL_STR
  1746.   Else
  1747.     sConnect = gsDataType
  1748.   End If
  1749.   
  1750.   'set the database name for non Jet and Btrieve dbs that
  1751.   'came from the Common Dialog
  1752.   If gsDataType <> gsJETMDB And gsDataType <> gsBTRIEVE And _
  1753.      gsDataType <> gsEXCEL50 And doit = False Then
  1754.     'need to strip off filename for these dbs
  1755.     sDatabaseName = StripFileName(gsDBName)
  1756.     gsDBName = sDatabaseName
  1757.   Else
  1758.     sDatabaseName = gsDBName
  1759.   End If
  1760.  
  1761. OneMoreTry:
  1762.   If (frmMDI.dlgCMD1.Flags And FileOpenConstants.cdlOFNReadOnly) = FileOpenConstants.cdlOFNReadOnly Then
  1763.     gnReadOnly = True
  1764.   Else
  1765.     gnReadOnly = False
  1766.   End If
  1767.   Set gdbCurrentDB = gwsMainWS.OpenDatabase(sDatabaseName, False, gnReadOnly, sConnect)
  1768.   If gbDBOpenFlag = True Then
  1769.     CloseAllRecordsets
  1770.     CloseAllPropForms
  1771.     CloseAllListCombos
  1772.   End If
  1773.   gbTransPending = False
  1774.  
  1775.   frmMDI.Caption = "VisData:" & sDatabaseName
  1776.   gdbCurrentDB.QueryTimeout = glQueryTimeout
  1777.  
  1778.   'success
  1779.   gbDBOpenFlag = True
  1780.   ShowDBTools
  1781.   RefreshTables frmTables.lstTables, True
  1782.  
  1783.   AddMRU
  1784.   If gsDataType <> gsJETMDB Then
  1785.     MsgBar "NOTE: Use of Attached Tables is the Recommended Method", False
  1786.   End If
  1787.   Screen.MousePointer = vbDefault
  1788.  
  1789.   Exit Sub
  1790.  
  1791. AttemptRepair:
  1792.   SetHourglass
  1793.   MsgBar "Repairing " & gsDBName, True
  1794.   DBEngine.RepairDatabase gsDBName
  1795.   Screen.MousePointer = vbDefault
  1796.   GoTo OneMoreTry
  1797.  
  1798. OpenError:
  1799.   Screen.MousePointer = vbDefault
  1800.   If Err = 3049 Then
  1801.     If MsgBox(Error & gsNewLine & gsNewLine & "Attempt to Repair it?", 4 + 48) = gnMSGBOX_YES Then
  1802.       Resume AttemptRepair
  1803.     End If
  1804.   End If
  1805.   gbDBOpenFlag = False
  1806.   gsDBName = gsNULL_STR
  1807.   gsDataType = gsNULL_STR
  1808.   gsODBCDatabase = gsNULL_STR
  1809.   gsODBCUserName = gsNULL_STR
  1810.   gsODBCPassword = gsNULL_STR
  1811.   If Err <> 32755 And Err <> 3049 Then   'check for common dialog cancelled
  1812.     ShowError
  1813.   End If
  1814.   Exit Sub
  1815.  
  1816. End Sub
  1817.  
  1818. '------------------------------------------------------------
  1819. 'this sub is used to create a new directory for one
  1820. 'of the local ISAM data types
  1821. '------------------------------------------------------------
  1822. Sub NewLocalISAM()
  1823.    On Error GoTo NewISAMErr
  1824.  
  1825.    Dim sNewName As String
  1826.    Dim d As Database
  1827.  
  1828.    sNewName = InputBox("Enter Name for New ISAM Database:")
  1829.    If Len(sNewName) = 0 Then Exit Sub
  1830.  
  1831.    If Mid(sNewName, Len(sNewName), 1) <> "\" Then sNewName = sNewName & "\"
  1832.  
  1833.    MkDir Mid(sNewName, 1, Len(sNewName) - 1)
  1834.  
  1835.    gsDBName = sNewName
  1836.    OpenLocalDB True
  1837.  
  1838.    If gbDBOpenFlag = True Then
  1839.      ShowDBTools
  1840.      RefreshTables frmTables.lstTables, True
  1841.    End If
  1842.  
  1843.   Exit Sub
  1844.  
  1845. NewISAMErr:
  1846.   If Err = 75 Then Resume Next  'catch the case where dir exists
  1847.   ShowError
  1848.   Exit Sub
  1849.  
  1850. End Sub
  1851.  
  1852. '------------------------------------------------------------
  1853. 'this sub is called from the compact menu options
  1854. 'on the main MDI form
  1855. '------------------------------------------------------------
  1856. Sub CompactDB(rnCompactVersion As Integer)
  1857.   On Error GoTo CompactAccErr
  1858.  
  1859.   Dim sOldName As String
  1860.   Dim sNewName As String
  1861.   Dim sNewName2 As String
  1862.   Dim nEncrypt As Integer
  1863.  
  1864.   'get file name to compact
  1865.   frmMDI.dlgCMD1.Filter = "Jet Engine MDBs (*.mdb)|*.mdb"
  1866.   frmMDI.dlgCMD1.DialogTitle = "Select Jet Database to Compact"
  1867.   frmMDI.dlgCMD1.FilterIndex = 1
  1868.   frmMDI.dlgCMD1.Flags = FileOpenConstants.cdlOFNHideReadOnly
  1869.   frmMDI.dlgCMD1.ShowOpen
  1870.   If Len(frmMDI.dlgCMD1.FileName) > 0 Then
  1871.     sOldName = frmMDI.dlgCMD1.FileName
  1872.   Else
  1873.     Exit Sub
  1874.   End If
  1875.  
  1876.   'get file name to compact to
  1877.   frmMDI.dlgCMD1.DialogTitle = "Select Jet Database to Compact to"
  1878.   frmMDI.dlgCMD1.FilterIndex = 1
  1879.   frmMDI.dlgCMD1.FileName = gsNULL_STR
  1880.   frmMDI.dlgCMD1.CancelError = True
  1881.   frmMDI.dlgCMD1.Flags = FileOpenConstants.cdlOFNOverwritePrompt + FileOpenConstants.cdlOFNHideReadOnly
  1882.   frmMDI.dlgCMD1.ShowSave
  1883.   If Len(frmMDI.dlgCMD1.FileName) > 0 Then
  1884.     sNewName = frmMDI.dlgCMD1.FileName
  1885.     If Dir(sNewName) <> gsNULL_STR And sOldName <> sNewName Then
  1886.       Kill sNewName
  1887.     End If
  1888.   Else
  1889.     Exit Sub
  1890.   End If
  1891.  
  1892.   If MsgBox("Encrypt Compacted Database?", gnMSGBOX_TYPE) = vbYes Then
  1893.     nEncrypt = dbEncrypt
  1894.   Else
  1895.     nEncrypt = dbDecrypt
  1896.   End If
  1897.  
  1898.   SetHourglass
  1899.   MsgBar "Compacting " & sOldName & " to " & sNewName, True
  1900.   'if they want to overwrite the same file, we need to create a new MDB
  1901.   'and rename after the compact is successful
  1902.   If sOldName = sNewName Then
  1903.     sNewName2 = sNewName 'save the new name
  1904.     sNewName = Left(sNewName, Len(sNewName) - 1) & "N"
  1905.   End If
  1906.   
  1907.   DBEngine.CompactDatabase sOldName, sNewName, dbLangGeneral, rnCompactVersion + nEncrypt
  1908.   
  1909.   'check for an overwrite of the original mdb
  1910.   If VBA.Right(sNewName, 1) = "N" Then
  1911.     Kill sNewName2             'nuke the old one
  1912.     Name sNewName As sNewName2 'rename the new one to the original name
  1913.     sNewName = sNewName2       'reset to the correct name
  1914.   End If
  1915.   
  1916.   MsgBar gsNULL_STR, False
  1917.   Screen.MousePointer = vbDefault
  1918.  
  1919.   If MsgBox("Open Newly Compacted Database?", gnMSGBOX_TYPE) = vbYes Then
  1920.     If gbDBOpenFlag = True Then
  1921.       CloseCurrentDB
  1922.     End If
  1923.     gsDataType = gsJETMDB
  1924.     gsDBName = sNewName
  1925.     OpenLocalDB True
  1926.   End If
  1927.  
  1928.   If gbDBOpenFlag = True Then
  1929.     ShowDBTools
  1930.     RefreshTables frmTables.lstTables, True
  1931.   End If
  1932.  
  1933.   Exit Sub
  1934.  
  1935. CompactAccErr:
  1936.   If Err <> 32755 Then         'user cancelled
  1937.     ShowError
  1938.   End If
  1939.   Exit Sub
  1940.  
  1941. End Sub
  1942.  
  1943. '------------------------------------------------------------
  1944. 'this sub does some cleanup and shuts down VisData
  1945. '------------------------------------------------------------
  1946. Sub ShutDownVisData()
  1947.   On Error Resume Next
  1948.  
  1949.   Dim nRet As Integer
  1950.  
  1951.   'save all the current INI file settings
  1952.   SaveINISettings
  1953.  
  1954.   If gbDBChanged Then
  1955.     If MsgBox("Data has been changed, Commit it?", gnMSGBOX_TYPE) = gnMSGBOX_YES Then
  1956.       gwsMainWS.CommitTrans
  1957.     End If
  1958.   End If
  1959.  
  1960.   UnloadAllForms
  1961.   gdbCurrentDB.Close
  1962.   'close the help file
  1963.   nRet = OSWinHelp(frmMDI.hwnd, App.HelpFile, HelpConstants.cdlHelpQuit, 0)
  1964.   
  1965.   End
  1966.  
  1967. End Sub
  1968. Sub NewJetMDB(rnVersion As Integer)
  1969.   On Error GoTo NewAccErr
  1970.  
  1971.   Dim sNewName As String
  1972.   Dim db As Database
  1973.  
  1974.   'get file name to compact to
  1975.   frmMDI.dlgCMD1.DialogTitle = "Select Jet Database to Create"
  1976.   frmMDI.dlgCMD1.FilterIndex = 1
  1977.   frmMDI.dlgCMD1.Filter = "Jet Engine MDBs (*.mdb)|*.mdb"
  1978.   frmMDI.dlgCMD1.FileName = gsNULL_STR
  1979.   frmMDI.dlgCMD1.CancelError = True
  1980.   frmMDI.dlgCMD1.Flags = FileOpenConstants.cdlOFNOverwritePrompt + FileOpenConstants.cdlOFNHideReadOnly
  1981.   frmMDI.dlgCMD1.ShowSave
  1982.   If Len(frmMDI.dlgCMD1.FileName) > 0 Then
  1983.     sNewName = frmMDI.dlgCMD1.FileName
  1984.     If InStr(sNewName, ".") = 0 Then
  1985.       'add an extension if the user didn't supply one
  1986.       sNewName = sNewName & ".MDB"
  1987.     End If
  1988.     If Dir(sNewName) <> gsNULL_STR Then
  1989.       Kill sNewName
  1990.     End If
  1991.   Else
  1992.     Exit Sub
  1993.   End If
  1994.   If Len(sNewName) = 0 Then Exit Sub
  1995.  
  1996.   Set db = CreateDatabase(sNewName, dbLangGeneral, rnVersion)
  1997.   db.Close
  1998.  
  1999.   gsDataType = gsJETMDB
  2000.   gsDBName = sNewName
  2001.   OpenLocalDB True
  2002.   Exit Sub
  2003.  
  2004. NewAccErr:
  2005.   If Err <> 32755 Then         'user cancelled
  2006.     ShowError
  2007.   End If
  2008.   Exit Sub
  2009.  
  2010. End Sub
  2011.