Revit API Forum
Welcome to Autodesk’s Revit API Forums. Share your knowledge, ask questions, and explore popular Revit API topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

"Revit 2023 API: Missing Parameter Values When Exporting ViewSchedules to Excel"

5 REPLIES 5
SOLVED
Reply
Message 1 of 6
guillermogutierrezgcp
309 Views, 5 Replies

"Revit 2023 API: Missing Parameter Values When Exporting ViewSchedules to Excel"

Problem Summary

I am developing an add-in for Revit 2023 using C# and the Revit API. The goal is to export all schedules (ViewSchedules) to an Excel file, with each schedule being saved on a separate sheet. However, during the data extraction process, I encountered the following issues:

  1. Certain fields or values are missing in the export:

    • The column headers export correctly.
    • Some parameter values, particularly custom parameters (e.g., "Código"), do not appear in the corresponding rows or are left blank in the Excel file.
  2. Details of the Approach Used:

    • I am using TableData and TableSectionData to access the schedule data.
    • Column headers are retrieved using GetCellText(0, col).
    • Row data is retrieved using GetCellText(row, col).
  3. Data Verification in Revit:

    • Using RevitLookup, I have verified that the missing parameter values are present and correctly assigned in the schedules.
    • These parameters are visible in Revit and properly configured in the schedules.
  4. Technical Setup:

    • I am working with Revit 2023 and Visual Studio 2022.
    • The method GetCellElementId, which was previously used in older API versions to get the ElementId associated with a cell, is no longer available in the Revit 2023 API.

Specific Questions

  1. Why are some parameter values not exported correctly to the Excel file, even though they are visible in Revit?
  2. Is there a reliable way to access all custom parameters or linked values in schedules using the Revit 2023 API?
  3. Should I consider an alternative approach to extract detailed data from TableData or ViewSchedule in this API version?
Tags (1)
5 REPLIES 5
Message 2 of 6

Can you share a sample Revit file with the custom parameter, and the code you use to extract the details? Also refer, Revit API documentation under GetCellText Method which says;

Remarks:

For standard view schedules, to read the formatted text of the cell regardless of cell type, use GetCellText(SectionType, Int32, Int32) 

Message 3 of 6

This script is made in Revit 2025, although I'm not sure if you can use it in 2023.Check it out and then tell me. I also use Epplus to export to excel.
I hope it helps you.

public enum SectionType
{
    Header,
    Body
}
/// <summary>  
/// Constructs a new instance of the schedule exporter operating on the input schedule.  
/// </summary>  
/// <param name="input">The schedule to be exported.</param>  
internal class ExportSchedule(ViewSchedule input)
{
    /// <summary>  
    /// The schedule being exported.  
    /// </summary>  
    private readonly ViewSchedule theSchedule = input;

    public void ExportToExcel()
    {
        // Setup file location in the Documents folder  
        string folder = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
        string xlsxFile = Path.Combine(folder, ReplaceIllegalCharacters(theSchedule.Name) + ".xlsx");

        try
        {
            // Create an object to store schedule data  
            var scheduleData = new
            {
                theSchedule.Name,
                Header = GetSectionData(SectionType.Header), // Method to get header data  
                Body = GetSectionData(SectionType.Body)      // Method to get body data  
            };
            ExcelPackage.LicenseContext = LicenseContext.NonCommercial;

            // Genera el archivo Excel usando EPPlus  
            using (ExcelPackage excelPackage = new ExcelPackage())
            {
                // Crea una nueva hoja  
                ExcelWorksheet worksheet = excelPackage.Workbook.Worksheets.Add(theSchedule.Name);

                // Agrega el encabezado  
                int row = 1; // Comienza en la primera fila
                if (scheduleData.Header != null)
                {
                    for (int col = 0; col < scheduleData.Header.Count; col++)
                    {
                        worksheet.Cells[row, col + 1].Value = string.Join(", ", scheduleData.Header[col]);
                    }
                    // Mueve a la siguiente fila  
                    row++; 
                }

                // Agrega el cuerpo  
                if (scheduleData.Body != null)
                {
                    foreach (var bodyRow in scheduleData.Body)
                    {
                        for (int col = 0; col < bodyRow.Count; col++)
                        {
                            worksheet.Cells[row, col + 1].Value = bodyRow[col];
                        }
                        // Mueve a la siguiente fila  
                        row++; 
                    }
                } 

                if (File.Exists(xlsxFile))
                {
                    File.Delete(xlsxFile);
                    // Define el FileInfo con el nombre de archivo completo  
                    FileInfo excelFile = new FileInfo(xlsxFile);

                    // Guarda el archivo Excel  
                    excelPackage.SaveAs(excelFile);
                }
                else
                {
                    // Define el FileInfo con el nombre de archivo completo  
                    FileInfo excelFile = new FileInfo(xlsxFile);

                    // Guarda el archivo Excel  
                    excelPackage.SaveAs(excelFile);
                }
            }

            // Abre el archivo Excel usando Process.Start  
            ProcessStartInfo processStartInfo = new ProcessStartInfo
            {
                FileName = xlsxFile,
                UseShellExecute = true // Necesario para abrir el archivo  
            };
            Process.Start(processStartInfo);

            MessageBox.Show($"Archivo Excel generado en: {xlsxFile}");
        }
        catch (Exception ex)
        {
            MessageBox.Show($"Ocurrió un error: {ex.Message}");
            throw;
        }
    }


    /// <summary>  
    /// Gets the section data as a list of lists based on the section type.  
    /// </summary>  
    private List<List<string>> GetSectionData(SectionType sectionType)
    {
        var data = new List<List<string>>();
        TableSectionData sectionData = theSchedule.GetTableData().GetSectionData((int)sectionType);
        int numberOfRows = sectionData.NumberOfRows;
        int numberOfColumns = sectionData.NumberOfColumns;

        for (int iRow = sectionData.FirstRowNumber; iRow < numberOfRows; iRow++)
        {
            var rowData = new List<string>();
            for (int iCol = sectionData.FirstColumnNumber; iCol < numberOfColumns; iCol++)
            {
                // Get the cell's value  
                var cellValue = theSchedule.GetCellText((Autodesk.Revit.DB.SectionType)sectionType, iRow, iCol);
                if (!string.IsNullOrEmpty(cellValue))
                {
                    rowData.Add(cellValue);
                }
            }
            data.Add(rowData);
        }
        return data;
    }

    /// <summary>  
    /// An utility method to replace illegal characters in the schedule name when creating the JSON file name.  
    /// </summary>  
    /// <param name="stringWithIllegalChar">The schedule name.</param>  
    /// <returns>The updated string without illegal characters.</returns>  
    private static string ReplaceIllegalCharacters(string stringWithIllegalChar)
    {
        char[] illegalChars = Path.GetInvalidFileNameChars();

        string updated = stringWithIllegalChar;
        foreach (char ch in illegalChars)
        {
            updated = updated.Replace(ch, '_');
        }

        return updated;
    }
}

public Result Execute(
  ExternalCommandData commandData,
  ref string message,
  ElementSet elements)
{
    UIApplication uiapp = commandData.Application;
    
    View activeView = commandData.View;

    if (activeView is ViewSchedule)
    {
        ExportSchedule exporter = new(activeView as ViewSchedule);
        //bool bInteractive = app.IsJournalPlaying() ? false : true;
        exporter.ExportToExcel();
        return Result.Succeeded; 
    }
    else
    {
        message = "Unable to proceed: Active view must be a schedule.";
        return Result.Cancelled;
    }
}
Message 4 of 6

Hello,

Thank you for your response and willingness to help the community. I’m happy to share that I eventually found a solution, thanks to the code that @reylorente1 kindly shared with me. I’ve posted the final version of the code in his message.

Best regards,
Message 5 of 6

Hello sr, helped by your code i developed this last version. 

 

This tool exports all Revit schedules (ViewSchedules) to a single Excel file. It prompts the user to choose the output file path and format, supporting both XLSX and XLSM files. If the file exists, new worksheets are appended; otherwise, a new file is created. Each schedule is saved as a separate worksheet named after the schedule's title, including both header and body data. The Excel file is automatically opened after the export completes. This enhances efficiency by centralizing all schedule data into one organized Excel document

Message 6 of 6

Hi Gullermo, not long ago I shared a solution using Json, and then exported Excel. I also use Epplus, although you can use another library. Here I share the solution from Json to Excel.la solution to Json you can search at:
Exporting schedules to JSON

 

Hola Gullermo, no hace mucho compartir una solución usando Json,,para después exportar Excel. También uso Epplus, aunque se puede usa otra biblioteca. Aqui te comparto la solución desde Json a Excel.la solución a Json la puedes buscar en:
Exporting schedules to JSON:

public class ScheduleData
{
    public string Name { get; set; }
    public List<List<string>> Header { get; set; }
    public List<List<string>> Body { get; set; }
}
internal class ExportJSONToExcel
{
    public static void ConvertJsonToExcel(string jsonFilePath)
    {
        // Define el nombre de archivo aquí  
        string excelFileName = "ScheduleData.xlsx"; 
        
        string excelFilePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), excelFileName);

        try
        {
            // Lee el contenido del archivo JSON  
            string jsonData = File.ReadAllText(jsonFilePath);

            // Deserializa el jsonData en un objeto ScheduleData  
            var schedule = JsonConvert.DeserializeObject<ScheduleData>(jsonData);

            // Genera el archivo Excel usando EPPlus  
            using (ExcelPackage excelPackage = new ExcelPackage())
            {
                // Crea una nueva hoja  
                ExcelWorksheet worksheet = excelPackage.Workbook.Worksheets.Add(schedule.Name);

                // Agrega el encabezado  
                int row = 1; // Comienza en la primera fila  
                if (schedule.Header != null)
                {
                    for (int col = 0; col < schedule.Header.Count; col++)
                    {
                        worksheet.Cells[row, col + 1].Value = string.Join(", ", schedule.Header[col]);
                    }
                    row++; // Mueve a la siguiente fila  
                }

                // Agrega el cuerpo  
                if (schedule.Body != null)
                {
                    foreach (var bodyRow in schedule.Body)
                    {
                        for (int col = 0; col < bodyRow.Count; col++)
                        {
                            worksheet.Cells[row, col + 1].Value = bodyRow[col];
                        }
                        row++; // Mueve a la siguiente fila  
                    }
                }

                // Define el FileInfo con el nombre de archivo completo  
                FileInfo excelFile = new FileInfo(excelFilePath);

                // Guarda el archivo Excel  
                excelPackage.SaveAs(excelFile);
            }

            // Abre el archivo Excel usando Process.Start  
            ProcessStartInfo processStartInfo = new ProcessStartInfo
            {
                FileName = excelFilePath,
                UseShellExecute = true // Necesario para abrir el archivo  
            };
            Process.Start(processStartInfo);

            MessageBox.Show($"Archivo Excel generado en: {excelFilePath}");
        }
        catch (Exception ex)
        {
            MessageBox.Show($"Ocurrió un error: {ex.Message}");
        }
    }


}

 

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report