尝试创建对象列表时出错 - 索引超出范围(Google.APIs.Sheets.v4.Data.ValueRange)

时间:2017-07-14 16:13:00

标签: .net vb.net google-api google-api-dotnet-client google-sheets-api

我无法将这些嵌套列表包裹起来。

对于Google表格API来插入数据,我必须从我理解的列表列表中传递行和列。

我怎么也想不出如何加载列表中的值。

        Dim requestBody As New ValueRange()

        Dim rowCount As Integer = 2

        requestBody.Values = New List(Of IList(Of Object))() From {New List(Of Object)()}

        requestBody.Values(0).Add(1)
        requestBody.Values(0).Add(2)
        requestBody.Values(0).Add(3)
        requestBody.Values(0).Add(4)
        requestBody.Values(0).Add(5)
        requestBody.Values(1).Add("a")
        requestBody.Values(1).Add("b")
        requestBody.Values(1).Add("c")
        requestBody.Values(1).Add("d")
        requestBody.Values(1).Add("e")

当我到达第二个值(行)时,我收到一个错误:索引超出范围。

System.ArgumentOutOfRangeException: 'Index was out of range. Must be non-negative and less than the size of the collection.'

感谢您的帮助。

PS如果有人可以分享将DataTable转换为此对象(列表列表)的示例,那么循环遍历行并手动构建此对象会更容易,并且会永远感激。

https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/append

更新:这是我要创建的函数的完整代码。

Imports System.IO
Imports Google.Apis.Auth.OAuth2
Imports Google.Apis.Services
Imports Google.Apis.Sheets.v4
Imports Google.Apis.Sheets.v4.Data

Namespace Settings
    Public Class SettingsPage
        Inherits System.Web.UI.Page
        Dim _connstring As String

        Dim googleSecretJsonFilePath = Server.MapPath("GoogleSecret\GoogleSecret.json")
        Dim applicationName = "OPT Web Services"
        Dim scopes As String() = {SheetsService.Scope.Spreadsheets, SheetsService.Scope.Drive, SheetsService.Scope.DriveFile}
        Dim googleService = New GoogleService(googleSecretJsonFilePath, applicationName, scopes)
        Dim spreadSheetId = "14N-1R##########################sCWA7U" 'Private Live Sheet

        Protected Sub btnSendVersions_Click(sender As Object, e As EventArgs) Handles btnSendVersions.Click
            'TODO: Append KS_SedonaSync_Version to Google Docs - Tab
            'TODO: Append SS_Version to Google Docs

            Dim range = "'Customer OPT Versions'!A:E"
            'A (0)  - OPT_Customer_Number
            'B (1)  - Version_Id
            'C (2)  - Date_Installed
            'D (3)  - SedonaSync_Event_Id
            'E (4)  - Version

            Dim ds As DataSet = Master.OPTWebConfig.GetVersionList(_connstring)

            Dim sheetService = googleService.GetSheetsService()

            Dim valueInputOption As SpreadsheetsResource.ValuesResource.AppendRequest.ValueInputOptionEnum = SpreadsheetsResource.ValuesResource.AppendRequest.ValueInputOptionEnum.RAW
            Dim insertDataOption As SpreadsheetsResource.ValuesResource.AppendRequest.InsertDataOptionEnum = SpreadsheetsResource.ValuesResource.AppendRequest.InsertDataOptionEnum.INSERTROWS

            Dim requestBody As New ValueRange()

            'Update OPT Version Numbers
            Dim rowCount As Integer = ds.Tables("Versions").Rows.Count
            'TODO: Make this work: requestBody.Values = ds.Tables("Versions").Rows

            'Test Adding Multiple Rows, May need to loop through DataTable rows if we cannot find a way to convert the DataTable.
            requestBody.Values = New List(Of IList(Of Object))() From {New List(Of Object)()}
            requestBody.Values(0).Add(1)
            requestBody.Values(0).Add(2)
            requestBody.Values(0).Add(3)
            requestBody.Values(0).Add(4)
            requestBody.Values(0).Add(5)
            requestBody.Values(1).Add("a")
            requestBody.Values(1).Add("b")
            requestBody.Values(1).Add("c")
            requestBody.Values(1).Add("d")
            requestBody.Values(1).Add("e")

            Dim request As SpreadsheetsResource.ValuesResource.AppendRequest = sheetService.Spreadsheets.Values.Append(requestBody, spreadSheetId, range)
            request.ValueInputOption = valueInputOption
            request.InsertDataOption = insertDataOption
            Dim response = request.Execute()

            'TODO: Mark Rows in ds.Tables("Versions") as Sent_To_OPT = "Y" if Response is 200:OK
        End Sub
    End Class

    Public Class GoogleService
        Private ReadOnly _googleSecretJsonFilePath As String
        Private ReadOnly _applicationName As String
        Private ReadOnly _scopes As String()
        Public Sub New(googleSecretJsonFilePath As String, applicationName As String, scopes As String())
            _googleSecretJsonFilePath = googleSecretJsonFilePath
            _applicationName = applicationName
            _scopes = scopes
        End Sub
        Public Function GetGoogleCredential() As GoogleCredential
            Dim credential As GoogleCredential
            Using stream = New FileStream(_googleSecretJsonFilePath, FileMode.Open, FileAccess.Read)
                credential = GoogleCredential.FromStream(stream).CreateScoped(_scopes)
            End Using
            Return credential
        End Function
        Public Function GetSheetsService() As SheetsService
            Dim credential = GetGoogleCredential()
            Dim Base As New BaseClientService.Initializer
            Base.HttpClientInitializer = credential
            Base.ApplicationName = _applicationName
            Dim sheetsService = New SheetsService(Base)
            Return sheetsService
        End Function
    End Class
End Namespace

2 个答案:

答案 0 :(得分:1)

使用调试器很容易看出错误。我无权访问该API,因此以下只使用问题所在的List(Of List(Of Object)):在此行代码之后:

Dim requestBody As New List(Of IList(Of Object)) From {New List(Of Object)()}

调试器显示:

enter image description here

因此requestBody.Values集合中只有一个“行”(作为From {New List(Of Object)()的结果添加了。不会添加任何其他行。

' create collection, add row(0)
Dim Values As New List(Of IList(Of Object)) From {New List(Of Object)()}

Dim rowCount As Integer = 2

Values(0).Add(1)
Values(0).Add(2)
...

' add row(1)
Values.Add(New List(Of Object))
Values(1).Add("a")
Values(1).Add("b")
...

有了这样的事情,我的偏好就是做同样的事情并且忽略From...初始值设定项并以相同的方式添加所有行,这样就很容易了。错误的,未使用的rowCount使得它看起来像是一个循环所以这样做也会使它更容易。结果:

enter image description here

答案 1 :(得分:0)

那么有更清洁的选择吗?

        Dim rowCount As Integer = ds.Tables("Versions").Rows.Count
        requestBody.Values = New List(Of IList(Of Object))()
        Dim i As Integer = 0
        For Each row As DataRow In ds.Tables("Versions").Rows
            requestBody.Values.Add(New List(Of Object))
            requestBody.Values(i).Add(row.Item(0))
            requestBody.Values(i).Add(row.Item(1))
            requestBody.Values(i).Add(row.Item(2))
            requestBody.Values(i).Add(row.Item(3))
            requestBody.Values(i).Add(row.Item(4))
            i = i + 1
        Next