What's I'm doing well
I'm currently creating an dotnet core app to consume and process data from an Excel sheet stored in personal OneDrive. I'm using MSAL
to create a session token and the data consumption is working great. Here's my working code:
// Get the range for data to process
var dataRangeRequest = myGraphServiceClient // an instance of GraphServiceClient
.Me.Drive.Items[fileItemId]
.Workbook
.Sheets[sheetId]
.UsedRange(valuesOnly: false)
.Request();
var dataRange = await dataRangeRequest.GetAsync(ct)
// Extract column names (headers) from the data range
var columnNames = dataRange.Text.First.ToObject<string[]>();
// Extract data cells from the data range
var lines = dataRange.Text.Skip(1).Select(line=>line.ToObject<string[]>).ToArray();
[...] // Here I process the lines using the columnNames.
// --EVERYTHING WORKS UNTIL HERE--
What I'm not doing well
Now, I want to turn red a faulty data cell in the original Excel document
var faultyCell = (row: 34, column: 5); // the row/column offset of the faulty cell in dataRange
// ---------------------------------
// --FOLLOWING CODE IS NOT WORKING--
// ---------------------------------
var changeRange = new WorkbookRange
{
RowIndex = faultyCell.row,
ColumnIndex = faultyCell.column,
RowCount = 1,
ColumnCount = 1,
Format = new WorkbookRangeFormat {Fill = new WorkbookRangeFill {Color = "red"}}
};
await dataRangeRequest.PatchAsync(changeRange, ct); // Throwing a Microsoft.Graph.ServiceException
I intercepted the HTTP request & response and it's the following:
REQUEST
PATCH https://graph.microsoft.com/v1.0/me/drive/items/<file id>/workbook/worksheets/{sheetId}/microsoft.graph.usedRange(valuesOnly=true) HTTP/1.1
{
"columnIndex": 5,
"rowIndex": 34,
"columnCount": 1,
"rowCount": 1,
"format": {
"fill": {
"color": "Red",
"@odata.type": "microsoft.graph.workbookRangeFill"
},
"@odata.type": "microsoft.graph.workbookRangeFormat"
},
"@odata.type": "microsoft.graph.workbookRange"
}
RESPONSE
400 Bad Request
{
"error": {
"code": "BadRequest",
"message": "Bad Request - Error in query syntax.",
"innerError": {
"date": "<the date>",
"request-id": "<a guid>",
"client-request-id": "<another guid>"
}
}
}
Success with a manual HTTP request
I succeed to update manually the cell using a HTTP request by following the documentation.
WORKING REQUEST:
PATCH https://graph.microsoft.com/v1.0/me/drive/items/<file id>/workbook/worksheets/{sheetId}/range(address='F35:F35')/format/fill
{"color": "red"}
Problems
- I don't know how to generate this HTTP request from C# by using the
Microsoft.Graph
api. (the documentation is obsoleted, there's no.Format
onIWorkbookWorksheetRangeRequestBuilder
. This error seems documented on GitHub. Is there an easy way to use the graph SDK to send an arbritary http request? - More importantly: for this to work, I need to translate the cell offset to a range address. Is there an utility somewhere to do that? In my example I manually translated the offset
5,34
in the range to addressF35
.
Specifications
Packages:
Microsoft.Graph
:v3.15.0
(latest release version)Microsoft.Identity.Client
: (MSAL)v4.15.0
(not the latest version, but shoudn't be a problem here)
I can confirm, that this issue with no
.Format
onIWorkbookWorksheetRangeRequestBuilder
is frustrating for me as well ;) I've reported this issue on GitHub:https://github.com/microsoftgraph/msgraph-sdk-dotnet/issues/233
For me the workaround was to do it like so (i was basing it on this SOF: REST call to Microsoft Graph
Whereas
workbookRange
variable is of either of type:WorkbookRangeFill
orWorkbookRangeFont
(Depending on the need) I assume you will be interested inWorkbookRangeFill
(to change the color in range/cell)range
variable is range in spreadsheet in the format: "A1:B3"resource
variable isformat/fill
forWorkbookRangeFill
andformat/font
forWorkbookRangeFont
and of course
{user id}
is the user which owns the document (i am usingclient credentials flow with
withapplication permisions
For other scenarios i assume you can just change one thing in the code above. So that, instead of:https://graph.microsoft.com/v1.0/users/{user id}/drive
to use
https://graph.microsoft.com/v1.0/me/drive