Friday, September 4, 2020

Get Menu item path on D365FO Menu in excel

 Hi

At times during designing security architecture for our D365FO implementation we need list of all entry points(Menu item path) on our D365FO menu in an excel file. So that, we could plan the access to them a lot easier. To fulfill this purpose we could use the script written below in D365FO runnable class and get the output in excel for later use.

Script:

using System.IO;

using OfficeOpenXml;

using OfficeOpenXml.Style;

using OfficeOpenXml.Table;

using Microsoft.Dynamics.AX.Metadata.MetaModel;

class GetMenuItems

{

    public static void main(Args _args)

    {

        SysDictMenu      _menu;

        str              formName;

        str             menuItemName;

        int             currentRow;

        MemoryStream    memoryStream = new MemoryStream();

        boolean iterateMenus(SysDictMenu _cmenu, OfficeOpenXml.ExcelRange cells, OfficeOpenXml.ExcelRange cell)

        {

            SysMenuEnumerator menuEnum = _cmenu.getEnumerator();

            SysDictMenu subMenu;

            SysDictMenu parentSubMenu;

            boolean found;

            while (menuEnum.moveNext())

            {

                currentRow ++;

                subMenu = menuEnum.current();

                if (subMenu.isMenu() || subMenu.isMenuReference())

                {

                    if(subMenu.isMenuReference())

                    {

                        cell = cells.get_Item(currentRow, 1);

                    }

                    else

                    {

                        cell = cells.get_Item(currentRow, 2);

                    }

                    cell.set_Value(subMenu.label());

                    cell = null;

                    found = iterateMenus(subMenu,cells,cell);

                    if (found)

                    {

                        return found;

                    }

                }

                else if ((subMenu.isMenuItem()&& subMenu.menuItem().type() == MenuItemType::Display && subMenu.isVisible())

                              || (subMenu.isMenuItem()&& subMenu.menuItem().type() == MenuItemType::Action && subMenu.isVisible())

                    || (subMenu.isMenuItem()&& subMenu.menuItem().type() == MenuItemType::Output && subMenu.isVisible())

                              || (subMenu.isTileReference() && subMenu.isVisible()))

                {

                    cell = cells.get_Item(currentRow, 3);

                    cell.set_Value(subMenu.label());

                    cell = null;

                }

            }

            return false;

        }

        using (var package = new ExcelPackage(memoryStream))

        {

            currentRow = 1;

            var worksheets = package.get_Workbook().get_Worksheets();

            var menuItemWorksheet = worksheets.Add("Menu List");

            var cells = menuItemWorksheet.get_Cells();

            OfficeOpenXml.ExcelRange cell = cells.get_Item(currentRow, 1);

            System.String value = "Main menu";

            cell.set_Value(value);

            cell = null;

            value = "Sub menu";

            cell = cells.get_Item(currentRow, 2);

            cell.set_Value(value);

            cell = null;

            value = "Menu item";

            cell = cells.get_Item(currentRow, 3);

            cell.set_Value(value);

            _menu = SysDictMenu::newMenuName(menuStr(MainMenu));

            if(_menu)

            {

                iterateMenus(_menu,cells,cell);

            }

            package.Save();

            file::SendFileToUser(memoryStream, "Menu Item List.xlsx");

        }

    }

}