2

In the Smartsheet c# SDK, the row.ParentRowId is helpful, but I'm not seeing a means to determine what level in the hierarchy a given row is? For example, if I have something like...

  • Project Name
    • Section 1
      • Task 1
      • Task 2
    • Section 2
      • Task 3
      • Task 4

In Microsoft project there is an "Outline level" field that would have a "1" for Project Name, a "2" for Section 1 and Section 2, and a "3" for each of the tasks in my example.

I don't see how to determine (or change) the "Outline level" of a row using Smartsheet's SDK.

Thanks,

Eric
  • 3
  • 3
Ken
  • 41
  • 3

2 Answers2

0

With the Smartsheet API, the fact that a row is a child row of another row is indicated by the presence of the parentId attribute on the Row object. If present, that property on a Row object specifies the value of the parent row’s Id.

Regarding the C# SDK specifically, this attribute is exposed as the ParentId property of the Row object (note capitalization of “ParentId”). Using the C# SDK:

  • If the ParentId property IS null on a Row object in a response, this indicates that the Row is a top-level row (i.e., is not a child of any other row).
  • If the ParentId property of a Row object is NOT null, this indicates that the Row is a child of the row that has Id corresponding to the ParentId value.

The following code snippet uses the C# SDK to identify row hierarchy by examining ParentId value for each Row in a Sheet.

// Set the Access Token.
Token token = new Token();
token.AccessToken = YOUR_ACCESS_TOKEN;

// Use the Smartsheet Builder to create a Smartsheet.
SmartsheetClient smartsheet = new SmartsheetBuilder().SetAccessToken(token.AccessToken).Build();

// Get Sheet.
long sheetId = YOUR_SHEET_ID;
Sheet sheet = smartsheet.SheetResources.GetSheet(sheetId, null, null, null, null, null, null, null);

// Identify Row hierarchy by examining the ParentId property of each row.
foreach (Row row in sheet.Rows)
{
    if (row.ParentId != null)
    {
        Response.Write("Row #" + row.RowNumber.ToString() + " (Id=" + row.Id.ToString() + ") is a child of Row Id " + row.ParentId.ToString() + "<br/><br/>");
    }
    else
    {
        Response.Write("Row #" + row.RowNumber.ToString() + " (Id=" + row.Id.ToString() + ") is a top-level row.<br/><br/>");
    }
}

The Smartsheet API does not currently expose a property that’s analogous to “outline level” — but you should be able to derive the “outline level” of each Row by using the ParentId property as described above.

You change the "outline level" (i.e., indent) of a row using the Smartsheet API by using the location specifier Row attributes described here in the API docs: http://smartsheet-platform.github.io/api-docs/#row-include-flags.

Using the C# SDK, you’d specify some combination of the location specifier Row attributes when you call the Row.AddRowBuilder(…) function to describe where the row should be placed in the sheet, relative to other already-existing rows. The documentation that I’ve linked to above describes the placement results you’ll get from setting various combinations of the location specifier attributes for a row.

For example, the following script adds a new row as the first child row under the specified parent row:

// Set the Access Token.
Token token = new Token();
token.AccessToken = YOUR_ACCESS_TOKEN;

// Use the Smartsheet Builder to create a Smartsheet.
SmartsheetClient smartsheet = new SmartsheetBuilder().SetAccessToken(token.AccessToken).Build();

// Get Sheet.
long sheetId = YOUR_SHEET_ID;
Sheet sheet = smartsheet.SheetResources.GetSheet(sheetId, null, null, null, null, null, null, null);

// Identify Row hierarchy by examining the ParentId property of each row.
foreach (Row row in sheet.Rows)
{
    if (row.ParentId != null)
    {
        Response.Write("Row #" + row.RowNumber.ToString() + " (Id=" + row.Id.ToString() + ") is a child of Row Id " + row.ParentId.ToString() + "<br/><br/>");
    }
    else
    {
        Response.Write("Row #" + row.RowNumber.ToString() + " (Id=" + row.Id.ToString() + ") is a top-level row.<br/><br/>");
    }
}

/************************************************
 * Add new row.
/************************************************/

// Specify cell values for the row.
Cell[] cells = new Cell[] { new Cell.AddCellBuilder(2069395137685380, "New Task").Build(), new Cell.AddCellBuilder(4743407416436612, "Added via API").SetStrict(false).Build() };

// Specify the Id of the parent row.
long parentId = 1085142354683780;

// Specify contents and placement of new row.
// Use the 5 parameters of the "AddRowBuilder" function to specify row's placement: toTop, toBottom, parentId, siblingId, above
// Specifying parentId only will add the new row as the first child row under the specified parent row.
Row newRow = new Row.AddRowBuilder(null, null, parentId, null, null).SetCells(cells).Build();

// Add row to sheet.
smartsheet.SheetResources.RowResources.AddRows(sheetId, new Row[] { newRow });
Kim Brandl
  • 13,125
  • 2
  • 16
  • 21
0

Here's what I did to get keep track of our indentation. Each indent is a level. So in my image Row 2 would be have a level 2 and Row 7 would have a level 3. Row 8, would have a level 2 and it's parent row number would be 7 (row 7).

enter image description here

foreach (var detailRow in detailSheet.Rows)
{
     long rowId = (detailRow.Id.HasValue) ? detailRow.Id.Value : 0;
     long parentId = (detailRow.ParentId.HasValue) ? detailRow.ParentId.Value : 0;

     int parentRowNumber = 0;
     int level = 0;

     if (parentId != 0)
     {
         foreach (RowLevel lvl in rowLevelList)
         {
             if (lvl.RowId != parentId) continue;

             parentRowNumber = lvl.Row;
             level = lvl.Level + 1;
             break;
         }
     }

     RowLevel rowLevel = new RowLevel();
     rowLevel.RowId = rowId;
     rowLevel.ParentId = parentId;
     rowLevel.Row = detailRow.RowNumber.Value;
     rowLevel.ParentRowNumber = parentRowNumber;
     rowLevel.Level = level;
     rowLevelList.Add(rowLevel);

     System.Diagnostics.Debug.WriteLine("Row: " + detailRow.RowNumber);
     System.Diagnostics.Debug.WriteLine("Row Id: " + rowId);
     System.Diagnostics.Debug.WriteLine("Parent Id: " + parentId);
     System.Diagnostics.Debug.WriteLine("Parent Row Number: " + parentRowNumber);
     System.Diagnostics.Debug.WriteLine("Level: " + level);
     System.Diagnostics.Debug.WriteLine("");
}

A little class to keep track of levels and parent row numbers

private class RowLevel
{
   public int Row = 0;
   public int Level = 0;
   public int ParentRowNumber = 0;
   public long ParentId = 0;
   public long RowId = 0;
}

enter image description here

Hope this helps!

thatstevedude
  • 195
  • 1
  • 2
  • 14