3
votes

I would like to update a cell value in Google Spreadsheets but unfortunatelly an error is received:

Google.GData.Client.GDataRequestException was unhandled
  HResult=-2146233088
  Message=Execution of request failed: https://spreadsheets.google.com/feeds/cells/1nW8nxoS2l9pbj6dctreEfKHNXmsfbbsCAvOd7TIj4Bo/od6/private/full/R1C1
  Source=Google.GData.Client
  ResponseString=Missing resource version ID
  StackTrace:
   at Google.GData.Client.GDataRequest.Execute()
   ...
   at System.Threading.ThreadHelper.ThreadStart()
InnerException: System.Net.WebException
   HResult=-2146233079
   Message=The remote server returned an error: (400) Bad Request.
   Source=System
   StackTrace:
        at System.Net.HttpWebRequest.GetResponse()
        at Google.GData.Client.GDataRequest.Execute()

My code is very simple and is based on sample downloaded from https://developers.google.com/google-apps/spreadsheets/?csw=1#changing_contents_of_a_cell:

        SpreadsheetsService service = new SpreadsheetsService("MySpreadsheetIntegration-v1");

        // TODO: Authorize the service object for a specific user (see other sections)
        service.setUserCredentials("...", "...");            

        // Instantiate a SpreadsheetQuery object to retrieve spreadsheets.
        SpreadsheetQuery query = new SpreadsheetQuery();

        // Make a request to the API and get all spreadsheets.
        SpreadsheetFeed feed = service.Query(query);

        foreach (SpreadsheetEntry spreadsheet in feed.Entries)
        {
            if (spreadsheet.Title.Text == "Test01")
            {
                // Get the first worksheet of the first spreadsheet.
                WorksheetFeed wsFeed = spreadsheet.Worksheets;
                WorksheetEntry worksheet = (WorksheetEntry)wsFeed.Entries[0];

                // Fetch the cell feed of the worksheet.
                CellQuery cellQuery = new CellQuery(worksheet.CellFeedLink);
                cellQuery.MinimumRow = 1;
                cellQuery.MaximumRow = 10;
                cellQuery.MinimumColumn = cellQuery.MaximumColumn = 1;
                cellQuery.ReturnEmpty = ReturnEmptyCells.yes;
                CellFeed cellFeed = service.Query(cellQuery);

                // Iterate through each cell, updating its value if necessary.
                foreach (CellEntry cell in cellFeed.Entries)
                {
                    cell.InputValue = "Foooooo!";
                    cell.Update();
                }

            }
        }

The error is raised on the following line:

                    cell.Update();

I use Google.GData version 2.2.0.0 (http://code.google.com/p/google-gdata/). Do you know what could cause this problem?

[Edit] This issue has also been reported in the gdata python client. Hope it gets fixed soon. http://code.google.com/p/gdata-python-client/issues/detail?id=692&sort=-opened&colspec=Opened%20Stars%20ID%20Type%20Status%20Priority%20Component%20Summary

Thank you!

2
I had this error. Was just a case of add it in. It used to be optional, but no longer is. - eddyparkinson
What exactly do you mean by "add it in"? - oneee
Sorry was in a rush. Looks like you have the ID I was thinking of, i.e. SpreadsheetsService("MySpreadsheetIntegration-v1"); .... Are you using the old style spreadsheet (400,000 cell limit). Last I read, it does not work with new style spreadsheet, is work in progress. .... Also I use batch update as using single cell updates is slow. - eddyparkinson
Update: As on Apr 1st all gdata writes stopped working. I get "Unusual traffic from your computer network" as described here, but reads work just fine. support.google.com/websearch/answer/86640 - eddyparkinson
I'm using new Spreadsheets. It works fine in old Spreadsheet. I think that "Unusual traffic" is a different problem not connected to this one. - oneee

2 Answers

6
votes

We hit this same issue about a week ago when it seems that Google flipped over all spreadsheets to the "new" format.
This goes for new ones created via the GData api as well. 400 errors everywhere.

I dug into the reports across the GData variant libraries (Python, Java, .Net etc) and eventually found this little nugget: https://stackoverflow.com/a/23438381/1685090

Setting the Etag property to "*" is the answer :)

To be clear, we're setting WorksheetEntry.Etag when we want to run Update() on a worksheet, and we're also setting CellEntry.Etag when doing batch updates via SpreadsheetsService.Batch().

So far it seems to work fine with Google's "new" spreadsheets.

One catch with this approach is that any concurrent/merging operations will be foregone - essentially you are telling Google that your update must blow away any other concurrent prior value in the cells.

1
votes

Another way I solved this is through adding an additional HTTP header

If-Match: *

Which says overwrite anything.