Tuesday, October 25, 2011

How to unhide grid views

We all know how you can right-click on the grid of a form and use MorphX to add fields, remove fields, etc. You can also save and load views of a grid. Have you ever accidentally right-clicked on a form and clicked "hide" and not been able to figure out how to unhide?

In the example below, I have clicked "Load" to see all the views I could load for this grid. I then right-clicked on my list and said "Hide."


Now that I've hidden it, I cannot right-click and "unhide." I've lost my list of views. The only way to fix it is to remove a record from your usage data.

Go to Tools > Options to modify your own usage data or go to Admin > Users > select the user that is having this issue, click on the "User options" button. From there, click the "Usage data" button. Go to the last tab that says "All usage data." Highlight the row that has Record Type = UserSetup and Name = SysPick (see below) and delete that record (hit the big red X at the top of the form or press Alt-F9).

Friday, October 21, 2011

Calling AIF Web Service - not sending all the fields into AX

We had the occasion to call the Dynamics AX SalesOrder create web service. However, we were trying to pass in the SalesOrder.SalesType field and it wouldn't come through in the XML that AIF read. The element and the attribute were not there in the XML file. We spoke with someone at Microsoft and they told us that you had to use the "specified" property on the field. For example (this is C#):

salesOrder.SalesType = AxdEnum_SalesType.Sales;
salesOrder.SalesTypeSpecified = true;

This seemed to do the trick!

Limiting user sessions

Our company has a limited number of AX user licenses, as most companies will. Some people like to open multiple sessions (and eat up licenses) while they're working. We have asked people to stop this and we close their sessions when we notice that they have multiples open, but we wanted some way for the system to prevent this from happening.

I read about this idea on another blog, but I didn't save the link. It's the same general idea as they proposed, but I did it a little differently, in the end.

I created a table called UserSessionLimits. It has a field called UserID (extended data type is userId) and this is a mandatory field. It has another field called MaxSessions (this is an integer) and it also is mandatory. The index is UserIDx, it contains userid and it is unique.

The code that accesses this table is written so that if a user is not in this table, then they are limited to one session, so add users to this table if they are exceptions and you want them to be able to have more than one session open.

Add code to the "Info" class, in the startup() method. The Info class can only be accessed by going to the System Documentation area of the AOT.

In the startup method, at the top, I placed this code:

select count(recid) from sysClientSessions
where sysClientSessions.userId == curuserid() &&
sysClientSessions.Status == 1 &&
sysClientSessions.clientType == 0;

if(sysClientSessions.RecId > UserSessionLimits::getMaxSessions(curUserid()))
{
box::stop(strfmt("You have exceeded your session limit of %1, the application will now close",
UserSessionLimits::GetMaxSessions(curUserid())));
appl.globalcache().set(classstr(info),identifierStr(AutoLogoff), true);
this.shutDown(true);
}

By searching only for clientType = 0, you will only be looking for "User" sessions. Web sessions or worker sessions (batches that are running) will not be affected.

There have been times that people have gotten around this. They quickly opened two sessions immediately one after the other. If they are simultaneously opened, it's hard to catch. Also, sometimes this locks people out. If they were doing something and AX shut down on them or their system froze, sometimes it takes some time for the session to end for them to get back in again. Your network administrator can control when inactive sessions time out.

We also set automatic shutdown (in user options) to 60 minutes. So if their session is inactive for 60 minutes, it will close.

Update:
So we implemented this and found that sometimes people would see this box and never click OK. It is the user interaction that causes the session to close. So if they just leave the session up with the box open, then they can still open up a bunch of sessions and eat up our licenses. So we changed the code to show a progress box for 5 seconds instead of a box that requires user interaction. I made this a utility in case we ever needed a progress box that would show a message for a period time and then close automatically, we could call this code again. Here is the code:

static void timedProgressBox(int timetoWait, str caption, str text)
{
    #AviFiles
    AppTimer timer = new AppTimer();
    SysOperationProgress  progress = new SysOperationProgress();
    int i ;
    ;

    timer.Start();

    progress.setAnimation(#AviStopWatch);
    progress.setText(text);
    progress.setCaption(caption);
    progress.setTotal(timetoWait);

    for (i = 0; timer.time() < timetoWait; i++)
    {
        timer.ticks();
        progress.setCount(i,1);
        i = real2int(timer.time());
    }

    progress.kill();

    timer.Stop();
}


FTP in and out of Dynamics AX

Axaptapedia has a good article on this:
http://axaptapedia.com/index.php?title=FTP_from_Axapta.

I pretty much followed their instructions and then tweaked the code to work for our needs.

Just a few notes on it:
1. I added the InteropPermission assert before setting the handle.
2. I had to use the IP address of our FTP server instead of the ftp.company.com address.
3. My set current directory looked something like "folder//subfolder" don't forget the double slashes.
4. My put file is on another server so I had to do something like (handle,"\\\\server\\folder\\folder2\\folder3\\xmlfile.xml","XMLFile.xml"); Lots of slashes involved.
5. The get file requires the handle, then the file you are going to get, then the file location and name that you want it to create.

The upload worked great. I'm having issues with the download, but only because I think the user that I'm logging into on the FTP server does not have permission to access the file location that I'm trying to put it to. I'll follow up on this post when we have it working. I could download it to my C: drive fine though. All in all, a success!

Wednesday, August 17, 2011

Dynamics AX 2009 - removing new line character from string (note/memo/text) fields

So this is my first post on this dynamics AX blog of mine. I'm going to use this to keep track of the little programming solutions I develop. Maybe it will help someone else too. Who knows?

My customer was having problems with a report showing the delivery address in excel. When a new line character is reached, it moves to another line. This made the excel format untenable for our 3rd party vendor that needed the data. So I wrote this code on the report to strip the new line character out and replace it with a space.

display str DeliveryStreet()
{
TextBuffer txt = new TextBuffer();
;

txt.setText(dataSource.DeliveryStreet);
txt.replace('\n',' ');
dataSource.DeliveryStreet = txt.getText();

return(dataSource.DeliveryStreet);
}

The DeliveryStreet field on the report calls this method instead of calling the field on the datasource.