ArgumentOutOfRangeException,我无法弄清楚为什么

时间:2018-06-13 19:48:56

标签: powershell ado ms-access-2013

我正在构建一个PowerShell脚本,用于检索存储在MS Access 2013数据库文件中的一些信息。查询是从机器上收集的其他一些数据动态构建的。我采用了完整的模块化方法,并将所有数据库功能和管理放在一个单独的模块中,我使用“使用模块”语句引入(功能相当大,所以我认为这样会更容易管理代码)。除openRecordSet函数外,一切似乎都运行良好。

以下是我的数据库类的构造函数以及我的connectToDatabase方法和openRecordSet方法:

Database($dbPath) {
    $this.connectToDatabase($dbPath)
}

connectToDatabase($Db) {
    $this.databasePath = $Db
    $this.connection = New-Object -ComObject ADODB.Connection
    $this.connection.Open("Provider = Microsoft.ACE.OLEDB.12.0;Data Source='$Db'")
    if ($this.connection -eq $NULL -OR $this.connection.State -eq $this.adStateClosed) {
        throw "$this.DatabasePath found but a valid connection could not be made."
    }
}

[object] openRecordSet($query, $cursorType, $lockType) {
    $RecordSet = New-Object -ComObject ADODB.Recordset
    Write-Host "query = $query"
    return $RecordSet.Open($query, $this.connection, $cursorType, $lockType)
}

这是给我问题的代码。它是在另一个类中,在执行到达此行时成功创建了数据库对象和连接:

$RecSet = $this.database.openRecordSet($query, 3, 1)

使用Visual Studio Code的调试模式,Write-Host语句并在MS Access中运行它,我已确认$query内的SQL语句是正确的。第二个参数是游标类型,在此实例中为Dynamic,第三个参数是lock类型,在此实例中为ReadOnly。我使用的是我在Database类中定义的常量,但是将它们更改为原始数值以确认那些不会导致问题。错误没有改变。以下是错误消息:

Index was out of range. Must be non-negative and less than the size of the
collection.
Parameter name: index
At C:\Users\FakeUser\Documents\MySuperScript\modules\userprofiles.psm1:20 char:21
+ ...                  $RecSet = $this.database.openRecordSet($query, 3, 1)
+                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : OperationStopped: (:) [], ArgumentOutOfRangeException
    + FullyQualifiedErrorId : System.ArgumentOutOfRangeException

我无法弄清楚导致此错误的原因。 $query是一个字符串,$this.connection是一个comObject连接。我在不同的脚本中使用了相同的语法,没有任何问题,只有当我开始使用模块时才发生这种情况。当然这是一个简单的语法问题或其他一些我忽略的简单事情。

1 个答案:

答案 0 :(得分:2)

Open方法的返回类型无效。弹出错误是因为您要将void转换为对象以便返回它。 这是ADODB.Recordset

的列表
_xClone():ADODB.Recordset (Method)
_xResync(AffectRecords:ADODB.AffectEnum):System.Void (Method)
_xSave(FileName:System.String, PersistFormat:ADODB.PersistFormatEnum):System.Void (Method)
AbsolutePage:ADODB.PositionEnum (Get Property)
AbsolutePage:System.Void (Set Property)
AbsolutePosition:ADODB.PositionEnum (Get Property)
AbsolutePosition:System.Void (Set Property)
ActiveCommand:System.Object (Get Property)
ActiveConnection:System.Object (Get Property)
ActiveConnection:System.Void (Set Property)
AddNew(FieldList:System.Object, Values:System.Object):System.Void (Method)
BOF:System.Boolean (Get Property)
Bookmark:System.Object (Get Property)
Bookmark:System.Void (Set Property)
CacheSize:System.Int32 (Get Property)
CacheSize:System.Void (Set Property)
Cancel():System.Void (Method)
CancelBatch(AffectRecords:ADODB.AffectEnum):System.Void (Method)
CancelUpdate():System.Void (Method)
Clone(LockType:ADODB.LockTypeEnum):ADODB.Recordset (Method)
Close():System.Void (Method)
Collect:System.Object (Get Property)
Collect:System.Void (Set Property)
CompareBookmarks(Bookmark1:System.Object, Bookmark2:System.Object):ADODB.CompareEnum (Method)
CursorLocation:ADODB.CursorLocationEnum (Get Property)
CursorLocation:System.Void (Set Property)
CursorType:ADODB.CursorTypeEnum (Get Property)
CursorType:System.Void (Set Property)
DataMember:System.String (Get Property)
DataMember:System.Void (Set Property)
DataSource:System.Object (Get Property)
DataSource:System.Void (Set Property)
Delete(AffectRecords:ADODB.AffectEnum):System.Void (Method)
EditMode:ADODB.EditModeEnum (Get Property)
EOF:System.Boolean (Get Property)
Fields:ADODB.Fields (Get Property)
Filter:System.Object (Get Property)
Filter:System.Void (Set Property)
Find(Criteria:System.String, SkipRecords:System.Int32, SearchDirection:ADODB.SearchDirectionEnum, Start:System.Object):System.Void (Method)
GetRows(Rows:System.Int32, Start:System.Object, Fields:System.Object):System.Object (Method)
GetString(StringFormat:ADODB.StringFormatEnum, NumRows:System.Int32, ColumnDelimeter:System.String, RowDelimeter:System.String, NullExpr:System.String):System.String (Method)
Index:System.String (Get Property)
Index:System.Void (Set Property)
let_ActiveConnection(pvar:System.Object):System.Void (Method)
let_Source(pvSource:System.String):System.Void (Method)
LockType:ADODB.LockTypeEnum (Get Property)
LockType:System.Void (Set Property)
MarshalOptions:ADODB.MarshalOptionsEnum (Get Property)
MarshalOptions:System.Void (Set Property)
MaxRecords:System.Int32 (Get Property)
MaxRecords:System.Void (Set Property)
Move(NumRecords:System.Int32, Start:System.Object):System.Void (Method)
MoveFirst():System.Void (Method)
MoveLast():System.Void (Method)
MoveNext():System.Void (Method)
MovePrevious():System.Void (Method)
NextRecordset(RecordsAffected:System.Object&):ADODB.Recordset (Method)
Open(Source:System.Object, ActiveConnection:System.Object, CursorType:ADODB.CursorTypeEnum, LockType:ADODB.LockTypeEnum, Options:System.Int32):System.Void (Method)
PageCount:System.Int32 (Get Property)
PageSize:System.Int32 (Get Property)
PageSize:System.Void (Set Property)
Properties:ADODB.Properties (Get Property)
RecordCount:System.Int32 (Get Property)
Requery(Options:System.Int32):System.Void (Method)
Resync(AffectRecords:ADODB.AffectEnum, ResyncValues:ADODB.ResyncEnum):System.Void (Method)
Save(Destination:System.Object, PersistFormat:ADODB.PersistFormatEnum):System.Void (Method)
Seek(KeyValues:System.Object, SeekOption:ADODB.SeekEnum):System.Void (Method)
Sort:System.String (Get Property)
Sort:System.Void (Set Property)
Source:System.Object (Get Property)
Source:System.Void (Set Property)
State:System.Int32 (Get Property)
Status:System.Int32 (Get Property)
StayInSync:System.Boolean (Get Property)
StayInSync:System.Void (Set Property)
Supports(CursorOptions:ADODB.CursorOptionEnum):System.Boolean (Method)
Update(Fields:System.Object, Values:System.Object):System.Void (Method)
UpdateBatch(AffectRecords:ADODB.AffectEnum):System.Void (Method)

使用您的代码略微修改的示例:

Class Database  {
    [string] $databasePath
    $connection
    $adStateClosed

    Database($dbPath){
          $this.connectToDatabase($dbPath)
    }

    connectToDatabase($Db){
        $this.databasePath = $Db
        $this.connection = New-Object -ComObject ADODB.Connection
        $this.connection.Open("Provider = Microsoft.ACE.OLEDB.12.0;Data Source='$Db'" )
        if($this.connection -eq $NULL -OR $this.connection.State -eq $this.adStateClosed){
            Throw "$this.DatabasePath found but a valid connection could not be made."
        }
    }
    [object] openRecordSet([string] $query, $cursorType, $lockType){
        $RecordSet = new-object -ComObject ADODB.Recordset
        $RecordSet.Open($query, $this.connection, $cursorType, $lockType)
        return $RecordSet
    }
}


$db = [Database]::new("C:\MonthlySalesReport\MonthlySalesReports.accdb")
$query = "SELECT 1 AS CONNECTED"
$result = $db.openRecordSet($query, 3, 1)

for ($i = 0; $i -lt $result.RecordCount; $i++) {
    $record = $result[$i]
    Write-Host ($record.Name + " " + $record.Value)
}