Wednesday, April 25, 2012

Blog ceased

Hi there

I'm leaving Dynamics AX and so this Blog won't carry on. Thank you for reading the posts and - well, happy Daxing!

Btw.: If you need a new desktop wallpaper - here is one :) klick me!

Friday, January 6, 2012

New major release for SmartStart3000

Finally, and with huge delay (schedule for publish was October, but then, yeah - time flies, you know), the new version of SmartStart 3000 V.1.7 is now released.

Most significant feature is the AX 2012 support. Also some shortcuts for tools of AX 2012 are added.

Another new thingy is the free choice of the system tray icon. You can now refer to your favorite icon file; it will be used as Systray Icon for SmartStart. And the GUI has delighted with tool tips.

Several bugs have been fixed and help file is updated. And, even I gave my best, probably some new bugs found their way in. Please let me know if you have any trouble.

You can find the new release as usual on the SmartStart 3000 Central. There you find the download, product description, language support, help file, feedback form and so on ...

Many thanks to the translators!

Known Issue: The graphic rendering on Windows Vista and Windows 7 is not as smooth as it should be. In a funny way, this does not concern Windows XP and older Windows versions. But to optimize the graphics you can size the buttons to 48 pixels. I will keep an eye on that issue and fix it with a minor/revision release.


Wednesday, December 21, 2011

ChangeCompany: common.company() vs. common.dataAreaId

When you use the changeCompany(...) functionality and the company should be retrieved by a record's company you should always use

changeCompany(common.company())
{
    // do something in the specific company
}
instead of

changeCompany(common.dataAreaId)
{
    // do something in the specific company
}

Why? Because the dataAreaId can contain a virtual company aswell as a normal company, and if you try to do changeCompany(virtualCompany), this will interrupt with a runtime error. But the company() property returns always the selectable company which can properly used in a changeCompany(...) statement.

This works also with table views and crosscompany selections:

while select crosscompany:['Company1', 'Company2'] common
{
    changeCompany(common.company())
    {
        // do something in the specific company       
    }
}

By the way, probably unknown to much people, this company(...) property can be used before data modification to dictate operation company:

    // current company is Company1
    common.company('Company2');
    select firstonly common; // this will return the first row in Company2 even you are in Company1!

I think, this can minimize the use of changeCompany(...) if used wisely.

Tuesday, June 14, 2011

Change your Windows 7 into the Dynamics OS

Hi there

However, this time a funny post. Have you ever considered to change the Windows 7 Start Button (the blinky orb on the left in the task pane)? Since it is just a ressource in explorer.exe, it is quite easy to do.

  1. Download the 'Windows 7 button changer' from here:  http://luegisdorf.ch/w7btnChange2.6.exe (of course you can find it elsewere on the web too)
  2. Download the 'Dynamics Orb' from here: http://luegisdorf.ch/AX/6801_dynamics.bmp
  3. Make sure, your user has local administrator rights for the current machine
  4. Change properties for explorer.exe in (...\Windows\explorer.exe) as follow:
    1. Change owner to your account (security, advanced, owner)
    2. Change security settings to allow full access for current user
  5. Open the 'Windows 7 Button Changer' application, select the the downloaded bitmap file
  6. Revert settings for explorer.exe (remove rights, reset owner)
  7. Enjoy your new Dynamics OS!
And that's how it looks:
Idle

Hover


Pressed










Of course, you need to run the ''visual style", not the "classic style" ...

Monday, December 20, 2010

WinAPI::getTempFilename() im .NET Business Connector auf einer x64 Maschine

Ein Aufruf auf die externe Methode GetTempFileNameW auf Kernel32 verursacht eine Ausnahme, wenn sie im .NET Business Connector verwendet wird und dieser auf einem x64-System ausgeführt wird.

Das Problem betrifft zumindest AX 2009 (vielleicht AX 4.0 und AX 3.0 ebenfalls).

Als Workaround kann man folgenden Code verwenden:

fileName = System.IO.Path::GetTempFileName(); // returns a filename in the temporary directory

oder

fileName = CLRInterop::getAnytypeForObject(System.IO.Path::GetTempPath() )+ curuserid() + int642str(CLRInterop::getAnyTypeForObject(netTime.get_Ticks());


Egal wie man es löst, natürlich sollte man eine temporäre Datei nach Verwendung auch immer wieder löschen.

WinAPI::getTempFilename() in .NET Business Connector on a x64 machine

A call on the external method GetTempFileNameW on Kernel32 will raise an exception when called from the .NET Business Connector which is running on a x64 machine.

This problem applies at least in AX 2009 (may be on AX 4.0 and AX 3.0 too).

As a workaround you can use code such this:

fileName = System.IO.Path::GetTempFileName(); // returns a filename in the temporary directory

or

fileName = CLRInterop::getAnytypeForObject(System.IO.Path::GetTempPath() )+ curuserid() + int642str(CLRInterop::getAnyTypeForObject(netTime.get_Ticks());


However don't forget to delete the temporary file after, since it makes no sense to let garbage alive.

Friday, December 10, 2010

RLS in display methods on reports (AX 4.0)

X++ select statements do ignore Record Level Security (RLS) by default. With the property  recordLevelSecurity the behaviour to use Record Level Security can be modified. The property can also be used to retrieve the current behaviour.

But there is a difference to select statements inside display methods. Every select statement has activated Record Level Security if the command is in a scope inside a call stack with a display method root. But the current status is not really available trough the property recordLevelsSecurity. A call to this propery will return false, make you thinking Record Level Security is off - but it is not.

display showEmplName()
{
    EmplTable emplTable;
    EmplName name;
    ;
    info(strfmt("%1", emplTable.recordLevelSecurity())); // this will return false, but actually it's true!

    select firstonly Name from emplTable 
        where emplTable.EmplId == reportTable.emplId; // the record will use RLS (yeah, it's magic)

name = emplTable.Name;

    return name;
}

Even here the Record Level Security is on, without explicit change to recordLevelSecurity property:
display showEmplName()
{
    EmplName name;
    ;
    name = EmplTable::find(reportTable.EmplId); // the select inside the find method will use RLS even you haven't activate this

    return name;
}


If you want to ensure, that Record Level Security is really off, you need to touch the property explicit.
display showEmplName()
{
    EmplTable emplTable;
    EmplName name;
    ;
    emplTable.recordLevelSecurity(false); // this will really free from RLS   

    select firstonly Name from emplTable 
        where emplTable.EmplId == reportTable.emplId;

    name = emplTable.Name;

    return name;
}


This Problem appears in AX 4.0. In AX 2009 this phenomen does not exists; Record Level Security stays off until you change it explicit.