VERSION 1.0 CLASS BEGIN MultiUse = -1 'True END Attribute VB_Name = "Db" Attribute VB_GlobalNameSpace = False Attribute VB_Creatable = False Attribute VB_PredeclaredId = False Attribute VB_Exposed = False '========================================================================== ' Db - a single database connection (modern successor to the ADOp_* helpers ' in TheBigOne). Late-bound ADO, so no project reference is required; ' import the class and go. ' ' Defaults to the SQLOLEDB OLE DB provider (built into Windows - zero install, ' works for non-admin users), but Provider is settable. ' ' Dim db As New Db ' If db.OpenSqlServer("USMIDSQL01", "fanalysis") Then ' If db.Exec(batchSql) Then ... Else MsgBox db.LastError ' Dim a As Variant: a = db.Query("SELECT ...") ' 2D, row 1 = headers ' db.CloseConn ' End If '========================================================================== Option Explicit Private mConn As Object ' ADODB.Connection (late bound) Private mErr As String Private mProvider As String Private mTimeout As Long Private mRows As Long Private Sub Class_Initialize() mProvider = "SQLOLEDB" mTimeout = 600 End Sub Private Sub Class_Terminate() CloseConn Set mConn = Nothing End Sub '----- properties --------------------------------------------------------- Public Property Get Provider() As String Provider = mProvider End Property Public Property Let Provider(ByVal value As String) mProvider = value End Property Public Property Get CommandTimeout() As Long CommandTimeout = mTimeout End Property Public Property Let CommandTimeout(ByVal value As Long) mTimeout = value End Property Public Property Get LastError() As String LastError = mErr End Property Public Property Get RowsAffected() As Long RowsAffected = mRows End Property Public Property Get IsOpen() As Boolean IsOpen = (Not mConn Is Nothing) If IsOpen Then IsOpen = (mConn.State <> 0) End Property '----- open / close ------------------------------------------------------- ' Open a SQL Server connection. Integrated (Windows) security by default. Public Function OpenSqlServer(ByVal server As String, _ Optional ByVal database As String = "", _ Optional ByVal integratedSecurity As Boolean = True, _ Optional ByVal user As String = "", _ Optional ByVal password As String = "") As Boolean Dim cs As String cs = "Provider=" & mProvider & ";Data Source=" & server & ";" If Len(database) > 0 Then cs = cs & "Initial Catalog=" & database & ";" If integratedSecurity Then cs = cs & "Integrated Security=SSPI;" Else cs = cs & "User ID=" & user & ";Password=" & password & ";" End If OpenSqlServer = OpenConnString(cs) End Function ' Open with any provided connection string. Public Function OpenConnString(ByVal connString As String) As Boolean On Error GoTo fail mErr = "" If mConn Is Nothing Then Set mConn = CreateObject("ADODB.Connection") If mConn.State <> 0 Then mConn.Close mConn.Open connString OpenConnString = True Exit Function fail: mErr = "Open failed: " & Err.Number & " - " & Err.Description OpenConnString = False End Function Public Sub CloseConn() On Error Resume Next If Not mConn Is Nothing Then If mConn.State <> 0 Then mConn.Close End If End Sub '----- execute / query ---------------------------------------------------- ' Run a statement or multi-statement batch. RowsAffected is set after. Public Function Exec(ByVal sql As String) As Boolean On Error GoTo fail mErr = "": mRows = 0 If Not IsOpen Then mErr = "Connection is not open." Exec = False Exit Function End If mConn.CommandTimeout = mTimeout Dim affected As Variant mConn.Execute sql, affected If Not IsEmpty(affected) Then mRows = CLng(affected) Exec = True Exit Function fail: mErr = "Exec failed: " & Err.Number & " - " & Err.Description Exec = False End Function ' Run a query and return a 2D Variant array (1-based). Row 1 = headers when ' includeHeaders. Returns Empty on error or no columns; check LastError. Public Function Query(ByVal sql As String, Optional ByVal includeHeaders As Boolean = True) As Variant On Error GoTo fail mErr = "" If Not IsOpen Then mErr = "Connection is not open." Query = Empty Exit Function End If mConn.CommandTimeout = mTimeout Dim rs As Object Set rs = mConn.Execute(sql) Query = RecordsetToArray(rs, includeHeaders) On Error Resume Next rs.Close Exit Function fail: mErr = "Query failed: " & Err.Number & " - " & Err.Description Query = Empty End Function '----- helpers ------------------------------------------------------------ Private Function RecordsetToArray(ByVal rs As Object, ByVal includeHeaders As Boolean) As Variant Dim nCols As Long, i As Long, j As Long nCols = rs.Fields.Count If nCols = 0 Then RecordsetToArray = Empty Exit Function End If Dim block As Variant, nData As Long If Not (rs.BOF And rs.EOF) Then block = rs.GetRows ' 0-based (col, row) nData = UBound(block, 2) - LBound(block, 2) + 1 End If Dim hdrOff As Long hdrOff = IIf(includeHeaders, 1, 0) If nData + hdrOff = 0 Then RecordsetToArray = Empty Exit Function End If Dim out() As Variant ReDim out(1 To nData + hdrOff, 1 To nCols) If includeHeaders Then For j = 0 To nCols - 1 out(1, j + 1) = rs.Fields(j).Name Next j End If For i = 0 To nData - 1 For j = 0 To nCols - 1 out(i + 1 + hdrOff, j + 1) = block(j, i) Next j Next i RecordsetToArray = out End Function