public static async Task SetCellValue(IDialogContext context, string workbookId, string worksheetId, string cellAddress, object value)
        {
            try
            {
                var newValue = new WorkbookRange()
                {
                    Values = JToken.Parse($"[[\"{value}\"]]")
                };

                var headers = ServicesHelper.GetWorkbookSessionHeader(
                    await ExcelHelper.GetSessionIdForUpdateAsync(context));

                var updateRangeRequest = ServicesHelper.GraphClient.Me.Drive.Items[workbookId]
                                         .Workbook.Worksheets[worksheetId]
                                         .Range(cellAddress).Request(headers);

                var range = await updateRangeRequest.PatchAsync(newValue);

                await ServicesHelper.LogGraphServiceRequest(context, updateRangeRequest, newValue);

                await context.PostAsync($"**{cellAddress}** is now **{range.Text[0][0]}**");
            }
            catch (Exception ex)
            {
                await context.PostAsync($"Sorry, something went wrong setting the value of **{cellAddress}** to **{value.ToString()}** ({ex.Message})");
            }
        }
        public static async Task ReplyWithValue(IDialogContext context, string workbookId, string worksheetId, string cellAddress)
        {
            try
            {
                var headers = ServicesHelper.GetWorkbookSessionHeader(
                    ExcelHelper.GetSessionIdForRead(context));

                var rangeRequest = ServicesHelper.GraphClient.Me.Drive.Items[workbookId]
                                   .Workbook.Worksheets[worksheetId].Range(cellAddress).Request(headers);

                var range = await rangeRequest.GetAsync();

                await ServicesHelper.LogGraphServiceRequest(context, rangeRequest);

                if ((string)(range.ValueTypes[0][0]) != "Empty")
                {
                    await context.PostAsync($"**{cellAddress}** is **{range.Text[0][0]}**");
                }
                else
                {
                    await context.PostAsync($"**{cellAddress}** is empty");
                }
            }
            catch (Exception ex)
            {
                await context.PostAsync($"Sorry, something went wrong getting the value of **{cellAddress}** ({ex.Message})");
            }
        }
        public static async Task ReplyWithValue(IDialogContext context, string workbookId, WorkbookNamedItem namedItem)
        {
            try
            {
                switch (namedItem.Type)
                {
                case "Range":
                    var headers = ServicesHelper.GetWorkbookSessionHeader(
                        ExcelHelper.GetSessionIdForRead(context));

                    var namedItemRangeRequest = ServicesHelper.GraphClient.Me.Drive.Items[workbookId]
                                                .Workbook.Names[namedItem.Name].Range().Request(headers);

                    var range = await namedItemRangeRequest.GetAsync();

                    await ServicesHelper.LogGraphServiceRequest(context, namedItemRangeRequest);

                    if ((range.RowCount == 1) && (range.ColumnCount == 1))
                    {
                        // Named item points to a single cell
                        if ((string)(range.ValueTypes[0][0]) != "Empty")
                        {
                            await context.PostAsync($"**{namedItem.Name}** is **{range.Text[0][0]}**");
                        }
                        else
                        {
                            await context.PostAsync($"**{namedItem.Name}** is empty");
                        }
                    }
                    else
                    {
                        // Named item points to a range with multiple cells
                        var reply = $"**{namedItem.Name}** has these values:\n\n{GetRangeReply(range)}";
                        await context.PostAsync(reply);
                    }
                    break;

                case "String":
                case "Boolean":
                case "Integer":
                case "Double":
                    await context.PostAsync($"**{namedItem.Name}** is **{namedItem.Value}**");

                    break;

                default:
                    await context.PostAsync($"Sorry, I am not able to determine the value of **{namedItem.Name}** ({namedItem.Type}, {namedItem.Value})");

                    break;
                }
            }
            catch (Exception ex)
            {
                await context.PostAsync($"Sorry, something went wrong getting the value of **{namedItem.Name}** ({ex.Message})");
            }
        }
Exemplo n.º 4
0
        public static async Task DoOpenWorkbookAsync(IDialogContext context, string workbookName)
        {
            try
            {
                // Add extension to filename, if needed
                var filename = workbookName.ToLower();
                if (!(filename.EndsWith(".xlsx")))
                {
                    filename = $"{filename}.xlsx";
                }

                // Get meta data for the workbook
                var itemRequest = ServicesHelper.GraphClient.Me.Drive.Root.ItemWithPath(filename).Request();
                var item        = await itemRequest.GetAsync();

                await ServicesHelper.LogGraphServiceRequest(context, itemRequest);

                context.UserData.SetValue("WorkbookId", item.Id);
                context.ConversationData.SetValue("WorkbookName", item.Name);
                context.ConversationData.SetValue("WorkbookWebUrl", item.WebUrl);

                context.UserData.RemoveValue("Type");
                context.UserData.RemoveValue("Name");
                context.UserData.RemoveValue("CellAddress");
                context.UserData.RemoveValue("TableName");
                context.UserData.RemoveValue("RowIndex");

                // Get the first worksheet in the workbook
                var headers = ServicesHelper.GetWorkbookSessionHeader(
                    ExcelHelper.GetSessionIdForRead(context));

                var worksheetsRequest = ServicesHelper.GraphClient.Me.Drive.Items[item.Id]
                                        .Workbook.Worksheets.Request(headers).Top(1);

                var worksheets = await worksheetsRequest.GetAsync();

                await ServicesHelper.LogGraphServiceRequest(context, worksheetsRequest);

                context.UserData.SetValue("WorksheetId", worksheets[0].Name);

                // Respond
                await context.PostAsync($"We are ready to work with **{worksheets[0].Name}** in {ExcelHelper.GetWorkbookLinkMarkdown(context)}");
            }
            catch (Exception ex)
            {
                await context.PostAsync($"Sorry, something went wrong when I tried to open the **{workbookName}** workbook on your OneDrive for Business ({ex.Message})");
            }
        }
Exemplo n.º 5
0
        public static async Task DoSelectWorksheetAsync(IDialogContext context, string worksheetName)
        {
            try
            {
                var workbookId  = context.UserData.GetValue <string>("WorkbookId");
                var worksheetId = context.UserData.GetValue <string>("WorksheetId");

                // Check if we are already working with the new worksheet
                if (worksheetName.ToLower() == worksheetId.ToLower())
                {
                    await context.PostAsync($"We are already working with the **{worksheetId}** worksheet");

                    return;
                }

                // Check if the new worksheet exist
                var headers = ServicesHelper.GetWorkbookSessionHeader(
                    ExcelHelper.GetSessionIdForRead(context));

                var worksheetsRequest = ServicesHelper.GraphClient.Me.Drive.Items[workbookId]
                                        .Workbook.Worksheets.Request(headers);

                var worksheets = await worksheetsRequest.GetAsync();

                await ServicesHelper.LogGraphServiceRequest(context, worksheetsRequest);

                var lowerWorksheetName = worksheetName.ToLower();
                var worksheet          = worksheets.FirstOrDefault(w => w.Name.ToLower() == lowerWorksheetName);
                if (worksheet == null)
                {
                    await context.PostAsync($@"**{worksheetName}** is not a worksheet in the workbook. Type ""select worksheet"" to select the worksheet from a list");

                    return;
                }

                // Save the worksheet id
                context.UserData.SetValue <string>("WorksheetId", worksheet.Name);

                // Respond
                await context.PostAsync($"We are ready to work with the **{worksheet.Name}** worksheet");
            }
            catch (Exception ex)
            {
                await context.PostAsync($"Sorry, something went wrong selecting the {worksheetName} worksheet ({ex.Message})");
            }
        }
Exemplo n.º 6
0
        public static async Task DoListCharts(IDialogContext context)
        {
            var workbookId  = context.UserData.GetValue <string>("WorkbookId");
            var worksheetId = context.UserData.GetValue <string>("WorksheetId");

            try
            {
                var headers = ServicesHelper.GetWorkbookSessionHeader(
                    ExcelHelper.GetSessionIdForRead(context));

                var chartsRequest = ServicesHelper.GraphClient.Me.Drive.Items[workbookId]
                                    .Workbook.Worksheets[worksheetId].Charts.Request(headers);

                var charts = await chartsRequest.GetAsync();

                await ServicesHelper.LogGraphServiceRequest(context, chartsRequest);

                if (charts.Count > 0)
                {
                    var reply = new StringBuilder();

                    if (charts.Count == 1)
                    {
                        reply.Append($"There is **1** chart on **{worksheetId}**:\n");
                    }
                    else
                    {
                        reply.Append($"There are **{charts.Count}** on **{worksheetId}**:\n");
                    }

                    foreach (var chart in charts)
                    {
                        reply.Append($"* **{chart.Name}**\n");
                    }
                    await context.PostAsync(reply.ToString());
                }
                else
                {
                    await context.PostAsync($"There are no charts on {worksheetId}");
                }
            }
            catch (Exception ex)
            {
                await context.PostAsync($"Sorry, something went wrong getting the charts ({ex.Message})");
            }
        }
        public static async Task DoListNamedItems(IDialogContext context)
        {
            var workbookId = context.UserData.GetValue <string>("WorkbookId");

            try
            {
                var headers = ServicesHelper.GetWorkbookSessionHeader(
                    ExcelHelper.GetSessionIdForRead(context));

                var namedItemsRequest = ServicesHelper.GraphClient.Me.Drive.Items[workbookId]
                                        .Workbook.Names.Request(headers);

                var namedItems = await namedItemsRequest.GetAsync();

                await ServicesHelper.LogGraphServiceRequest(context, namedItemsRequest);

                if (namedItems.Count > 0)
                {
                    var reply = new StringBuilder();

                    if (namedItems.Count == 1)
                    {
                        reply.Append($"There is **1** named item in the workbook:\n");
                    }
                    else
                    {
                        reply.Append($"There are **{namedItems.Count}** named items in the workbook:\n");
                    }

                    foreach (var namedItem in namedItems)
                    {
                        reply.Append($"* **{namedItem.Name}**\n");
                    }
                    await context.PostAsync(reply.ToString());
                }
                else
                {
                    await context.PostAsync($"There are no named items in the workbook");
                }
            }
            catch (Exception ex)
            {
                await context.PostAsync($"Sorry, something went wrong getting the named items ({ex.Message})");
            }
        }
        public static async Task ReplyWithTableRow(IDialogContext context, string workbookId, WorkbookTable table, JToken row)
        {
            // Convert JToken
            var rowVals = JsonConvert.DeserializeObject <object[]>(row.ToString());

            if ((bool)(table.ShowHeaders))
            {
                // Get the table header
                var headers = ServicesHelper.GetWorkbookSessionHeader(
                    ExcelHelper.GetSessionIdForRead(context));

                var headerRequest = ServicesHelper.GraphClient.Me.Drive.Items[workbookId]
                                    .Workbook.Tables[table.Id].HeaderRowRange().Request(headers);

                var header = await headerRequest.GetAsync();

                await ServicesHelper.LogGraphServiceRequest(context, headerRequest);

                var reply     = new StringBuilder();
                var separator = "";
                for (var i = 0; i < rowVals.Length; i++)
                {
                    if ((rowVals[i] != null) && (((string)rowVals[i]) != string.Empty))
                    {
                        reply.Append($"{separator}* {header.Text[0][i]}: **{rowVals[i]}**");
                        separator = "\n";
                    }
                }
                await context.PostAsync(reply.ToString());
            }
            else
            {
                var reply     = new StringBuilder();
                var separator = "";
                for (var i = 0; i < rowVals.Length; i++)
                {
                    reply.Append($"{separator}* **{rowVals[i]}**");
                    separator = "\n";
                }
                await context.PostAsync(reply.ToString());
            }
        }
Exemplo n.º 9
0
        public static async Task DoListWorksheetsAsync(IDialogContext context)
        {
            var workbookId  = context.UserData.GetValue <string>("WorkbookId");
            var worksheetId = context.UserData.GetValue <string>("WorksheetId");

            try
            {
                var headers = ServicesHelper.GetWorkbookSessionHeader(
                    ExcelHelper.GetSessionIdForRead(context));

                var worksheetsRequest = ServicesHelper.GraphClient.Me.Drive.Items[workbookId]
                                        .Workbook.Worksheets.Request(headers);

                var worksheets = await worksheetsRequest.GetAsync();

                await ServicesHelper.LogGraphServiceRequest(context, worksheetsRequest);

                var reply = new StringBuilder();

                if (worksheets.Count == 1)
                {
                    reply.Append($"There is **1** worksheet in the workbook:\n");
                }
                else
                {
                    reply.Append($"There are **{worksheets.Count}** worksheets in the workbook:\n");
                }

                var active = "";
                foreach (var worksheet in worksheets)
                {
                    active = (worksheet.Name.ToLower() == worksheetId.ToLower()) ? " (active)" : "";
                    reply.Append($"* **{worksheet.Name}**{active}\n");
                }
                await context.PostAsync(reply.ToString());
            }
            catch (Exception ex)
            {
                await context.PostAsync($"Sorry, something went wrong getting the worksheets ({ex.Message})");
            }
        }
        // Lookup a name assuming that it is named item, return null if it doesn't exist
        public static async Task <Microsoft.Graph.WorkbookNamedItem> GetNamedItem(IDialogContext context, string workbookId, string name)
        {
            try
            {
                var headers = ServicesHelper.GetWorkbookSessionHeader(
                    ExcelHelper.GetSessionIdForRead(context));

                var namedItemsRequest = ServicesHelper.GraphClient.Me.Drive.Items[workbookId]
                                        .Workbook.Names.Request(headers);

                var namedItems = await namedItemsRequest.GetAsync();

                await ServicesHelper.LogGraphServiceRequest(context, namedItemsRequest);

                return(namedItems?.FirstOrDefault(n => n.Name.ToLower() == name.ToLower()));
            }
            catch
            {
                return(null);
            }
        }
Exemplo n.º 11
0
        // Lookup a name assuming that it is named item, return null if it doesn't exist
        public static async Task <WorkbookChart> GetChart(IDialogContext context, string workbookId, string worksheetId, string name)
        {
            WorkbookChart chart = null;

            try
            {
                var headers = ServicesHelper.GetWorkbookSessionHeader(
                    ExcelHelper.GetSessionIdForRead(context));

                var chartRequest = ServicesHelper.GraphClient.Me.Drive.Items[workbookId]
                                   .Workbook.Worksheets[worksheetId].Charts[name].Request(headers);

                chart = await chartRequest.GetAsync();

                await ServicesHelper.LogGraphServiceRequest(context, chartRequest);
            }
            catch
            {
            }
            return(chart);
        }
        // Lookup a name assuming that it is named item, return null if it doesn't exist
        public static async Task <WorkbookTable> GetTable(IDialogContext context, string workbookId, string name)
        {
            WorkbookTable table = null;

            try
            {
                var headers = ServicesHelper.GetWorkbookSessionHeader(
                    ExcelHelper.GetSessionIdForRead(context));

                var tableRequest = ServicesHelper.GraphClient.Me.Drive.Items[workbookId]
                                   .Workbook.Tables[name].Request(headers);

                table = await tableRequest.GetAsync();

                await ServicesHelper.LogGraphServiceRequest(context, tableRequest);
            }
            catch
            {
            }
            return(table);
        }
Exemplo n.º 13
0
        public async static Task <string[]> GetWorksheetNamesAsync(IDialogContext context, string workbookId)
        {
            try
            {
                var headers = ServicesHelper.GetWorkbookSessionHeader(
                    ExcelHelper.GetSessionIdForRead(context));

                var worksheetsRequest = ServicesHelper.GraphClient.Me.Drive.Items[workbookId]
                                        .Workbook.Worksheets.Request(headers);

                var worksheets = await worksheetsRequest.GetAsync();

                await ServicesHelper.LogGraphServiceRequest(context, worksheetsRequest);

                return(worksheets.Select <WorkbookWorksheet, string>(w => w.Name).ToArray());
            }
            catch (Exception)
            {
                return(new string[] { });
            }
        }
        public static async Task ReplyWithTable(IDialogContext context, string workbookId, WorkbookTable table)
        {
            try
            {
                var headers = ServicesHelper.GetWorkbookSessionHeader(
                    ExcelHelper.GetSessionIdForRead(context));

                var rangeRequest = ServicesHelper.GraphClient.Me.Drive.Items[workbookId]
                                   .Workbook.Tables[table.Id].Range().Request(headers);

                var range = await rangeRequest.GetAsync();

                await ServicesHelper.LogGraphServiceRequest(context, rangeRequest);

                var reply = $"**{table.Name}**\n\n{NamedItemsWorker.GetRangeReplyAsTable(range)}";
                await context.PostAsync(reply);
            }
            catch (Exception ex)
            {
                await context.PostAsync($"Sorry, something went wrong getting the **{table.Name}** table ({ex.Message})");
            }
        }
        public async Task SayHello(IDialogContext context, LuisResult result)
        {
            try
            {
                // Telemetry
                TelemetryHelper.TrackDialog(context, result, "Bot", "SayHello");

                // Did the bot already greet the user?
                bool saidHello = false;
                context.PrivateConversationData.TryGetValue <bool>("SaidHello", out saidHello);

                // Get the user data
                var userRequest = ServicesHelper.GraphClient.Me.Request();
                var user        = await userRequest.GetAsync();

                await ServicesHelper.LogGraphServiceRequest(context, userRequest);

                // Respond
                if (saidHello)
                {
                    await context.PostAsync($"Hi again, {user.GivenName}!");
                }
                else
                {
                    await context.PostAsync($"Hi, {user.GivenName}!");
                }

                // Record that the bot said hello
                context.PrivateConversationData.SetValue <bool>("SaidHello", true);
            }
            catch (Exception ex)
            {
                await context.PostAsync($"Sorry, something went wrong trying to get information about you ({ex.Message})");
            }
            context.Wait(MessageReceived);
        }
        public static async Task DoAddTableRow(IDialogContext context, object[] rows)
        {
            var workbookId = context.UserData.GetValue <string>("WorkbookId");

            string tableName = string.Empty;

            context.UserData.TryGetValue <string>("TableName", out tableName);

            try
            {
                if ((tableName != null) && (tableName != string.Empty))
                {
                    WorkbookTable table = null;

                    var headers = ServicesHelper.GetWorkbookSessionHeader(
                        await ExcelHelper.GetSessionIdForUpdateAsync(context));

                    try
                    {
                        var tablesRequest = ServicesHelper.GraphClient.Me.Drive.Items[workbookId]
                                            .Workbook.Tables[tableName].Request(headers);

                        table = await tablesRequest.GetAsync();

                        await ServicesHelper.LogGraphServiceRequest(context, tablesRequest);
                    }
                    catch
                    {
                    }

                    if (table != null)
                    {
                        // Get number of columns in table
                        var headerRequest = ServicesHelper.GraphClient.Me.Drive.Items[workbookId]
                                            .Workbook.Tables[table.Id].HeaderRowRange().Request(headers);

                        var tableHeaderRange = await headerRequest.GetAsync();

                        await ServicesHelper.LogGraphServiceRequest(context, headerRequest);

                        // Ensure that the row to be added has the right number of values. Add additional values, if needed
                        var checkedRows = new List <object>();
                        foreach (object[] uncheckedRow in rows)
                        {
                            if (uncheckedRow.Length < tableHeaderRange.ColumnCount)
                            {
                                var checkedRow = uncheckedRow.ToList();
                                while (checkedRow.Count < tableHeaderRange.ColumnCount)
                                {
                                    checkedRow.Add(null);
                                }
                                checkedRows.Add(checkedRow.ToArray());
                            }
                            else
                            {
                                checkedRows.Add(uncheckedRow);
                            }
                        }
                        // Add row
                        var newVals       = JToken.Parse(JsonConvert.SerializeObject(checkedRows));
                        var addRowRequest = ServicesHelper.GraphClient.Me.Drive.Items[workbookId]
                                            .Workbook.Tables[table.Id].Rows.Add(values: newVals).Request(headers);

                        var row = await addRowRequest.PostAsync();

                        await ServicesHelper.LogGraphServiceRequest(context, addRowRequest, newVals);

                        await context.PostAsync($"Added a new row to **{table.Name}**");

                        var rangeRequest = ServicesHelper.GraphClient.Me.Drive.Items[workbookId]
                                           .Workbook.Tables[table.Id].DataBodyRange().Request(headers);

                        var range = await rangeRequest.GetAsync();

                        await ServicesHelper.LogGraphServiceRequest(context, rangeRequest);

                        await ReplyWithTableRow(context, workbookId, table, range.Text[row.Index ?? 0]);
                    }
                    else
                    {
                        await context.PostAsync($"**{tableName}** is not a table in the workbook");
                    }
                }
                else
                {
                    await context.PostAsync($"Need the name of a table to add a row");
                }
            }
            catch (Exception ex)
            {
                await context.PostAsync($"Sorry, something went wrong adding the table row ({ex.Message})");
            }
        }
        public static async Task DoLookupTableRow(IDialogContext context, string value)
        {
            var workbookId = context.UserData.GetValue <string>("WorkbookId");

            string tableName = string.Empty;

            context.UserData.TryGetValue <string>("TableName", out tableName);

            try
            {
                if ((tableName != null) && (tableName != string.Empty))
                {
                    WorkbookTable table = null;

                    var headers = ServicesHelper.GetWorkbookSessionHeader(
                        ExcelHelper.GetSessionIdForRead(context));

                    try
                    {
                        var tablesRequest = ServicesHelper.GraphClient.Me.Drive.Items[workbookId]
                                            .Workbook.Tables[tableName].Request(headers);

                        table = await tablesRequest.GetAsync();

                        await ServicesHelper.LogGraphServiceRequest(context, tablesRequest);
                    }
                    catch
                    {
                    }

                    if (table != null)
                    {
                        if ((value != null) && (value != string.Empty))
                        {
                            var rangeRequest = ServicesHelper.GraphClient.Me.Drive.Items[workbookId]
                                               .Workbook.Tables[tableName].DataBodyRange().Request(headers);

                            var range = await rangeRequest.GetAsync();

                            await ServicesHelper.LogGraphServiceRequest(context, rangeRequest);

                            if ((range != null) && (range.RowCount > 0))
                            {
                                var lowerValue  = value.ToLower();
                                var rowIndex    = -1;
                                var columnIndex = 0;

                                while ((rowIndex < 0) && (columnIndex < range.ColumnCount))
                                {
                                    // Look for a full match in the first column of the table
                                    rowIndex = range.Text.IndexOf(r => (((string)(r[columnIndex])).ToLower() == lowerValue));
                                    if (rowIndex >= 0)
                                    {
                                        break;
                                    }
                                    else
                                    {
                                        // Look for a partial match in the first column of the table
                                        rowIndex = range.Text.IndexOf(r => (((string)(r[columnIndex])).ToLower().Contains(lowerValue)));
                                        if (rowIndex >= 0)
                                        {
                                            break;
                                        }
                                    }
                                    ++columnIndex;
                                }
                                if (rowIndex >= 0)
                                {
                                    context.UserData.SetValue <int>("RowIndex", rowIndex);
                                    await ReplyWithTableRow(context, workbookId, table, range.Text[rowIndex]);
                                }
                                else
                                {
                                    await context.PostAsync($"**{value}** is not in **{table.Name}**");
                                }
                            }
                            else
                            {
                                await context.PostAsync($"**{table.Name}** doesn't have any rows");
                            }
                        }
                        else
                        {
                            await context.PostAsync($"Need a value to look up a row in **{table.Name}**");
                        }
                    }
                    else
                    {
                        await context.PostAsync($"**{tableName}** is not a table in the workbook");
                    }
                }
                else
                {
                    await context.PostAsync($"Need the name of a table to look up a row");
                }
            }
            catch (Exception ex)
            {
                await context.PostAsync($"Sorry, something went wrong looking up the table row ({ex.Message})");
            }
        }
        public static async Task SetColumnValue(IDialogContext context, string workbookId, string tableName, string name, int rowIndex, object value)
        {
            var headers = ServicesHelper.GetWorkbookSessionHeader(
                await ExcelHelper.GetSessionIdForUpdateAsync(context));

            // Get the table
            var tableRequest = ServicesHelper.GraphClient.Me.Drive.Items[workbookId]
                               .Workbook.Tables[tableName].Request(headers);

            var table = await tableRequest.GetAsync();

            await ServicesHelper.LogGraphServiceRequest(context, tableRequest);

            if ((bool)(table.ShowHeaders))
            {
                // Get the table header
                var headerRequest = ServicesHelper.GraphClient.Me.Drive.Items[workbookId]
                                    .Workbook.Tables[table.Id].HeaderRowRange().Request(headers);

                var header = await headerRequest.GetAsync();

                await ServicesHelper.LogGraphServiceRequest(context, headerRequest);

                // Find the column
                var lowerName   = name.ToLower();
                var columnIndex = header.Text[0].IndexOf(h => h.ToString().ToLower() == lowerName);
                if (columnIndex >= 0)
                {
                    var rangeRequest = ServicesHelper.GraphClient.Me.Drive.Items[workbookId]
                                       .Workbook.Tables[table.Id].DataBodyRange().Request(headers);

                    var dataBodyRange = await rangeRequest.GetAsync();

                    await ServicesHelper.LogGraphServiceRequest(context, rangeRequest);

                    var rowAddress = ExcelHelper.GetRangeAddress(
                        (int)(dataBodyRange.ColumnIndex) + columnIndex,
                        (int)(dataBodyRange.RowIndex) + rowIndex,
                        1, 1);

                    var newValue = new WorkbookRange()
                    {
                        Values = JToken.Parse($"[[\"{value}\"]]")
                    };

                    var updateRangeRequest = ServicesHelper.GraphClient.Me.Drive.Items[workbookId]
                                             .Workbook.Worksheets[ExcelHelper.GetWorksheetName(dataBodyRange.Address)]
                                             .Range(rowAddress).Request(headers);

                    var range = await updateRangeRequest.PatchAsync(newValue);

                    await ServicesHelper.LogGraphServiceRequest(context, updateRangeRequest, newValue);

                    await context.PostAsync($"**{header.Text[0][columnIndex]}** is now **{range.Text[0][0]}**");
                }
                else
                {
                    await context.PostAsync($"**{name}** is not a column in **{table.Name}**");
                }
            }
            else
            {
                await context.PostAsync($"I cannot set values in **{table.Name}** because it does not have any headers");
            }
        }
        public static async Task SetNamedItemValue(IDialogContext context, string workbookId, string name, object value)
        {
            try
            {
                var namedItem = await GetNamedItem(context, workbookId, name);

                if (namedItem != null)
                {
                    switch (namedItem.Type)
                    {
                    case "Range":
                        var headers = ServicesHelper.GetWorkbookSessionHeader(
                            await ExcelHelper.GetSessionIdForUpdateAsync(context));

                        var namedItemRangeRequest = ServicesHelper.GraphClient.Me.Drive.Items[workbookId]
                                                    .Workbook.Names[namedItem.Name].Range().Request(headers);

                        var range = await namedItemRangeRequest.GetAsync();

                        await ServicesHelper.LogGraphServiceRequest(context, namedItemRangeRequest);

                        if ((range.RowCount == 1) && (range.ColumnCount == 1))
                        {
                            // Named item points to a single cell
                            try
                            {
                                var newValue = new WorkbookRange()
                                {
                                    Values = JToken.Parse($"[[\"{value}\"]]")
                                };

                                var updateRangeRequest = ServicesHelper.GraphClient.Me.Drive.Items[workbookId]
                                                         .Workbook.Worksheets[ExcelHelper.GetWorksheetName(range.Address)]
                                                         .Cell(range.RowIndex.Value, range.ColumnIndex.Value).Request(headers);

                                range = await updateRangeRequest.PatchAsync(newValue);

                                await ServicesHelper.LogGraphServiceRequest(context, updateRangeRequest, newValue);

                                await context.PostAsync($"**{namedItem.Name}** is now **{range.Text[0][0]}**");
                            }
                            catch (Exception ex)
                            {
                                await context.PostAsync($"Sorry, something went wrong setting the value of **{namedItem.Name}** to **{value}** ({ex.Message})");
                            }
                        }
                        else
                        {
                            await context.PostAsync($"Sorry, I can't set the value of **{namedItem.Name}** since it is a range of cells");
                        }
                        break;

                    case "String":
                    case "Boolean":
                    case "Integer":
                    case "Double":
                        await context.PostAsync($"Sorry, I am not able to set the value of **{namedItem.Name}** since it is a constant");

                        break;

                    default:
                        await context.PostAsync($"Sorry, I am not able to set the value of **{namedItem.Name}** ({namedItem.Type}, {namedItem.Value})");

                        break;
                    }
                }
                else
                {
                    await context.PostAsync($"**{name}** is not a named item in the workbook");
                }
            }
            catch (Exception ex)
            {
                await context.PostAsync($"Sorry, something went wrong setting the value of **{name}** ({ex.Message})");
            }
        }