Skip to content

Commit 6b68788

Browse files
committed
added checkHiddenExcelInstance to warn user about background excel (at startup and via checkpurgeNames)
added lookups refresh after DBSheet modifications, added additional encryption information to OLEDB connection string in DBListFetch if required by Encrypt=true in normal connection string added info about problems with encrypt=yes and packet size >16387 fixed AdHocSQL data grid problem with unrenderable data catch all exceptions in DBRowFetchAction
1 parent 398098d commit 6b68788

File tree

2 files changed

+70
-57
lines changed

2 files changed

+70
-57
lines changed

source/AdHocSQL.vb

+8
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ Public Class AdHocSQL
106106
Dim PrevSelDB As String = Me.Database.Text
107107
fillDatabasesAndSetDropDown()
108108
' reset previously set database
109+
If PrevSelDB = "" Then Exit Sub
109110
If Me.Database.Items.IndexOf(PrevSelDB) = -1 Then
110111
UserMsg("Previously selected database '" + PrevSelDB + "' doesn't exist in this environment !", "AdHoc SQL Command")
111112
End If
@@ -311,4 +312,11 @@ Public Class AdHocSQL
311312
If e.KeyCode = Keys.Escape Then finishForm(DialogResult.Cancel)
312313
End Sub
313314

315+
''' <summary>For non displayable data (blobs, etc.) that raise an exception, write out the exception in the datagrid cell tooltip instead of lots of popups</summary>
316+
''' <param name="sender"></param>
317+
''' <param name="e"></param>
318+
Private Sub AdHocSQLQueryResult_DataError(sender As Object, e As DataGridViewDataErrorEventArgs) Handles AdHocSQLQueryResult.DataError
319+
sender.CurrentRow.Cells(e.ColumnIndex).TooltipText = "Data raised exception: " + e.Exception.Message + " (" + e.Context.ToString() + ")"
320+
End Sub
321+
314322
End Class

source/Functions.vb

+62-57
Original file line numberDiff line numberDiff line change
@@ -1138,7 +1138,7 @@ err: LogWarn(errMsg + ", caller: " + callID)
11381138
Public Function DBRowFetch(<ExcelArgument(Description:="query for getting data")> Query As Object,
11391139
<ExcelArgument(Description:="connection string defining DB, user, etc...")> ConnString As Object,
11401140
<ExcelArgument(Description:="Range to put the data into", AllowReference:=True)> ParamArray targetArray() As Object) As String
1141-
Dim tempArray() As Excel.Range = Nothing ' final target array that is passed to makeCalcMsgContainer (after removing header flag)
1141+
Dim finalTargetArray() As Excel.Range = Nothing ' final target array that is passed to makeCalcMsgContainer (after removing header flag)
11421142
Dim callID As String = ""
11431143
Dim HeaderInfo As Boolean
11441144
Dim EnvPrefix As String = ""
@@ -1160,25 +1160,25 @@ err: LogWarn(errMsg + ", caller: " + callID)
11601160
If TypeName(targetArray(0)) = "Boolean" Or TypeName(targetArray(0)) = "String" Then
11611161
HeaderInfo = convertToBool(targetArray(0))
11621162
For i As Integer = 1 To UBound(targetArray)
1163-
ReDim Preserve tempArray(i - 1)
1163+
ReDim Preserve finalTargetArray(i - 1)
11641164
If IsNothing(ToRange(targetArray(i))) Then
11651165
DBRowFetch = EnvPrefix + ", Part " + i.ToString() + " of Target is not a valid Range !"
11661166
Exit Function
11671167
End If
1168-
tempArray(i - 1) = ToRange(targetArray(i))
1168+
finalTargetArray(i - 1) = ToRange(targetArray(i))
11691169
Next
11701170
ElseIf TypeName(targetArray(0)) = "ExcelEmpty" Or TypeName(targetArray(0)) = "ExcelError" Or TypeName(targetArray(0)) = "ExcelMissing" Then
11711171
' return appropriate error message...
11721172
DBRowFetch = EnvPrefix + ", First argument (header) " + Replace(TypeName(targetArray(0)), "Excel", "") + " !"
11731173
Exit Function
11741174
Else
11751175
For i = 0 To UBound(targetArray)
1176-
ReDim Preserve tempArray(i)
1176+
ReDim Preserve finalTargetArray(i)
11771177
If IsNothing(ToRange(targetArray(i))) Then
11781178
DBRowFetch = EnvPrefix + ", Part " + (i + 1).ToString() + " of Target is not a valid Range !"
11791179
Exit Function
11801180
End If
1181-
tempArray(i) = ToRange(targetArray(i))
1181+
finalTargetArray(i) = ToRange(targetArray(i))
11821182
Next
11831183
End If
11841184
' check query, also converts query to string (if it is a range)
@@ -1195,7 +1195,7 @@ err: LogWarn(errMsg + ", caller: " + callID)
11951195
StatusCollection.Add(callID, statusCont)
11961196
StatusCollection(callID).statusMsg = "" ' need this to prevent object not set errors in checkCache
11971197
ExcelAsyncUtil.QueueAsMacro(Sub()
1198-
DBRowFetchAction(callID, CStr(Query), caller, tempArray, CStr(ConnString), HeaderInfo)
1198+
DBRowFetchAction(callID, CStr(Query), caller, finalTargetArray, CStr(ConnString), HeaderInfo)
11991199
End Sub)
12001200
End If
12011201
Catch ex As Exception
@@ -1293,64 +1293,69 @@ err: LogWarn(errMsg + ", caller: " + callID)
12931293
DBModifs.preventChangeWhileFetching = True
12941294
If Not recordsetHasRows Then StatusCollection(callID).statusMsg = "Warning: No Data returned in query: " + Query
12951295

1296-
' if "heading range" is present then orientation of first range (header) defines layout of data: if "heading range" is column then data is returned column-wise, else row by row.
1297-
' if there is just one block of data then it is assumed that there are usually more rows than columns and orientation is set by row/column size
1298-
Dim fillByRows As Boolean = IIf(UBound(targetCells) > 0, targetCells(0).Rows.Count < targetCells(0).Columns.Count, targetCells(0).Rows.Count > targetCells(0).Columns.Count)
1299-
' put values (single record) from Recordset into targetCells
1300-
Dim fieldIter As Integer = 0 ' iterating through recordset fields
1301-
Dim rangeIter As Integer = 0 ' iterating through passed ranges
1302-
Dim headerFilled As Boolean = Not HeaderInfo ' if we don't need headers the assume they are filled already....
13031296
Dim totalFieldsDisplayed As Long = 0 ' needed to calculate displayedRows
1304-
Dim refCollector As Excel.Range = targetCells(0) ' needed to put together passed ranges to give dbftarget name to them
1305-
Do
1306-
Dim targetSlices As Excel.Range
1307-
If fillByRows Then
1308-
targetSlices = targetCells(rangeIter).Rows
1309-
Else
1310-
targetSlices = targetCells(rangeIter).Columns
1311-
End If
1312-
For Each targetSlice As Excel.Range In targetSlices
1313-
Dim aborted As Boolean = XlCall.Excel(XlCall.xlAbort) ' for long running actions, allow interruption
1314-
If aborted Then
1315-
errMsg = "data fetching interrupted by user !"
1316-
GoTo err
1297+
Try
1298+
' if "heading range" is present then orientation of first range (header) defines layout of data: if "heading range" is column then data is returned column-wise, else row by row.
1299+
' if there is just one block of data then it is assumed that there are usually more rows than columns and orientation is set by row/column size
1300+
Dim fillByRows As Boolean = IIf(UBound(targetCells) > 0, targetCells(0).Rows.Count < targetCells(0).Columns.Count, targetCells(0).Rows.Count > targetCells(0).Columns.Count)
1301+
' put values (single record) from Recordset into targetCells
1302+
Dim fieldIter As Integer = 0 ' iterating through recordset fields
1303+
Dim rangeIter As Integer = 0 ' iterating through passed ranges
1304+
Dim headerFilled As Boolean = Not HeaderInfo ' if we don't need headers the assume they are filled already....
1305+
Dim refCollector As Excel.Range = targetCells(0) ' needed to put together passed ranges to give dbftarget name to them
1306+
Do
1307+
Dim targetSlices As Excel.Range
1308+
If fillByRows Then
1309+
targetSlices = targetCells(rangeIter).Rows
1310+
Else
1311+
targetSlices = targetCells(rangeIter).Columns
13171312
End If
1318-
For Each theCell As Excel.Range In targetSlice.Cells
1319-
If Not recordsetHasRows Then
1320-
theCell.Value = ""
1321-
Else
1322-
If Not headerFilled Then
1323-
theCell.Value = recordset.GetName(fieldIter)
1313+
For Each targetSlice As Excel.Range In targetSlices
1314+
Dim aborted As Boolean = XlCall.Excel(XlCall.xlAbort) ' for long running actions, allow interruption
1315+
If aborted Then
1316+
errMsg = "data fetching interrupted by user !"
1317+
GoTo err
1318+
End If
1319+
For Each theCell As Excel.Range In targetSlice.Cells
1320+
If Not recordsetHasRows Then
1321+
theCell.Value = ""
13241322
Else
1325-
Try : theCell.Value = recordset.GetValue(fieldIter) : Catch ex As Exception
1326-
errMsg += "Field '" + recordset.GetName(fieldIter) + "' caused following error: '" + Err.Description + "'" ' don't break operation, just collect message
1327-
End Try
1328-
totalFieldsDisplayed += 1
1329-
End If
1330-
If fieldIter = recordset.FieldCount - 1 Then
1331-
' reached end of fields, get next data row
1332-
If headerFilled Then
1333-
recordsetHasRows = recordset.Read()
1334-
If recordsetHasRows Then returnedRows += 1
1323+
If Not headerFilled Then
1324+
theCell.Value = recordset.GetName(fieldIter)
13351325
Else
1336-
headerFilled = True
1326+
Try : theCell.Value = recordset.GetValue(fieldIter) : Catch ex As Exception
1327+
errMsg += "Field '" + recordset.GetName(fieldIter) + "' caused following error: '" + Err.Description + "'" ' don't break operation, just collect message
1328+
End Try
1329+
totalFieldsDisplayed += 1
1330+
End If
1331+
If fieldIter = recordset.FieldCount - 1 Then
1332+
' reached end of fields, get next data row
1333+
If headerFilled Then
1334+
recordsetHasRows = recordset.Read()
1335+
If recordsetHasRows Then returnedRows += 1
1336+
Else
1337+
headerFilled = True
1338+
End If
1339+
fieldIter = -1 ' reset field iterator
13371340
End If
1338-
fieldIter = -1 ' reset field iterator
13391341
End If
1340-
End If
1341-
fieldIter += 1
1342+
fieldIter += 1
1343+
Next
13421344
Next
1343-
Next
1344-
rangeIter += 1
1345-
If Not rangeIter > UBound(targetCells) Then refCollector = ExcelDnaUtil.Application.Union(refCollector, targetCells(rangeIter))
1346-
Loop Until rangeIter > UBound(targetCells)
1347-
' get rest of records for returned status message
1348-
While recordset.Read()
1349-
returnedRows += 1
1350-
End While
1351-
' delete the name to have a "clean" name area (otherwise visible = false setting wont work for dataTargetRange)
1352-
refCollector.Name = targetExtent
1353-
refCollector.Parent.Parent.Names(targetExtent).Visible = False
1345+
rangeIter += 1
1346+
If Not rangeIter > UBound(targetCells) Then refCollector = ExcelDnaUtil.Application.Union(refCollector, targetCells(rangeIter))
1347+
Loop Until rangeIter > UBound(targetCells)
1348+
' get rest of records for returned status message
1349+
While recordset.Read()
1350+
returnedRows += 1
1351+
End While
1352+
' delete the name to have a "clean" name area (otherwise visible = false setting wont work for dataTargetRange)
1353+
refCollector.Name = targetExtent
1354+
refCollector.Parent.Parent.Names(targetExtent).Visible = False
1355+
Catch ex As Exception
1356+
errMsg = "Error in filling target range: " + ex.Message + ", query: " + Query
1357+
GoTo err
1358+
End Try
13541359

13551360
If StatusCollection(callID).statusMsg.Length = 0 Then StatusCollection(callID).statusMsg = "Displayed " + Math.Ceiling(totalFieldsDisplayed / recordset.FieldCount).ToString() + " of " + returnedRows.ToString() + " record" + If(returnedRows > 1 Or returnedRows = 0, "s", "") + " from: " + Query + IIf(errMsg <> "", ";Errors: " + errMsg, "")
13561361
finishAction(calcMode, callID)

0 commit comments

Comments
 (0)