Thank you to the person who made me aware that the article here:
Comcom and the Bus adapter
Misses out a couple of important things. So I will try to correct that here.
When you set up NAS to read from Microsoft Message Queues (MSMQ), using the MSMQ Bus Adapter as described in the article above, then you must remember these two things:
1) The label on any message you send to the queue, must be "Navision MSMQ-BA". Otherwise NAS will ignore them, and they will stay in the queue. This is a way to control which messages are intented for NAS. It is a hardcoded feature, and cannot be adjusted or changed or disabled.
2) Text in the messages must be in the format UTF-8. NAS (or any other NAV component) does not recognise UNICODE and any other format than UTF-8 can make the message unreadable.
So if everything else seems to be OK, but NAS still does not read messages from MSMQ, then check these two things.
Lars Lohndorf-Larsen (Lohndorf )
Microsoft Dynamics UK
When using Send-to Excel option from NAV, decimals are exported as texts if Digit grouping symbol (Control Panel - Regional and Language Options) is a ' ' (whitespace). NAV uses ANSI 160 code character for space, which is not a space in ascii code table (normally used by windows applications). Consequently, decimals larger then 1000 (thus containing a space as digit grouping symbol) will be interpreted as text by excel.
This has been corrected in a new style sheet released for this issue.
The issue is also corrected in 5.0 SP1 update 1 (using style hseets provided with SP1).
To correct this issue, open the style sheet file in notepad, default file is NavisionFormToExcel, placed in Stylesheet folder of the Client folder. Browse to the following line :
<xsl:variable name="DecimalSeparator" select="Object/DecimalSeparator"/>
and add a line
<xsl:variable name="DecimalSeparator" select="Object/DecimalSeparator"/> <xsl:variable name="nbsp"> </xsl:variable> <!-- LINE ADDED !-->
Then locate and modify the following sections (modifications marked in code):
<xsl:template match="Control[@type='TextBox']"> <Cell xmlns="urn:schemas-microsoft-com:office:spreadsheet"> <xsl:choose> <xsl:when test="contains(@value,'..')"> <xsl:attribute name="ss:StyleID">TextBox</xsl:attribute> </xsl:when> <xsl:when test="@value = translate(@value,',.','')"> <xsl:attribute name="ss:StyleID">TextBox</xsl:attribute> </xsl:when>
<!-- BEGIN modifications, the following section was modified !-->
<xsl:attribute name="ss:StyleID">TextBoxNumber</xsl:attribute> </xsl:when>
<!-- END modifications !-->
<xsl:otherwise> <xsl:attribute name="ss:StyleID">TextBox</xsl:attribute> </xsl:otherwise>
</xsl:choose> <Data> <xsl:choose>
<!-- BEGIN modifications, the following section was modified !-->
<xsl:when test="string(number(translate(translate(@value,$nbsp,''),',.','11')))!='NaN'"> <xsl:choose> <xsl:when test="contains(@value,'..')"> <xsl:attribute name="ss:Type">String</xsl:attribute> <xsl:value-of select="@value"/> </xsl:when>
<xsl:when test="translate(@value,$nbsp,'') = translate(translate(@value,$nbsp,''),',.','')"> <xsl:attribute name="ss:Type">Number</xsl:attribute> <xsl:value-of select="translate(@value,$nbsp,'')"/> </xsl:when>
<xsl:when test="$DecimalSeparator = '.'"> <xsl:attribute name="ss:Type">Number</xsl:attribute> <xsl:value-of select="translate(translate(@value,$nbsp,''),',','')"/> </xsl:when> <xsl:when test="$DecimalSeparator = ','"> <xsl:attribute name="ss:Type">Number</xsl:attribute> <xsl:value-of select="translate(translate(translate(@value,$nbsp,''),'.',''),',','.')"/> </xsl:when>
<xsl:otherwise> <xsl:attribute name="ss:Type">Number</xsl:attribute> <xsl:value-of select="translate(translate(translate(@value,$nbsp,''),'.',''),',','.')"/> </xsl:otherwise> </xsl:choose> </xsl:when>
<xsl:otherwise> <xsl:attribute name="ss:Type">String</xsl:attribute> <xsl:value-of select="@value"/> </xsl:otherwise> </xsl:choose> </Data>
<!-- END modifications !-->
Jasminka Vukovic (jvukovic )
Microsoft Dynamics NO
Microsoft Customer Service and Support (CSS) EMEA
What was more irritating was that the system was working most of the time, and, of course, there was no way to consistently reproduce the issue.
I will explain the issue here, hoping that people don't make the same mistake again.
Think about a single instance code unit which is receiving an event in order to process the incoming data (this was using the ComCom objects), and, in order to catch possible errors in the AL execution, a NAV Timer (Navision Timer) is used to reply successfully or with an error to the receiving event initiator (the COM component that started the conversation).
Normal flow (from the NAS perspective) was:
Sounds reasonable, and in most cases this would work great. However, people were experiencing mixed up answers especially when errors were to be reported.
Of course, my first thought was that the component connecting to the NAS was the guilty one, as, after all, it is a multi-thread, multi-connection component (it runs as a Windows Service), and getting all this threads straight is always a tricky business. However, after inspecting the components code, and correcting some issues, the problem was still there.
I decided it was time to get the hands really dirty and started making my own component which would simulate the system and start hammering the NAS with requests using multiple threads and inspecting the replies, and sure enough, especially when the NAS would error, the replies would contain a different ID than the original sending ID on the same virtual connection.
So, there must be something in the NAS that does not work correctly. More code inspection, but nothing showed up until.... Hey, wait a second... We are using a global variable to save data and then reusing this data later on when the NTimer event fires, and, since the NAS is single threaded, this should all work fine, right?
Well, of course the first thing that came into my mind was that there was a possibility that a new incoming event would be "queued" before the NTimer event would be scheduled, and this would mean that a new MessageReceived event would be triggered before the NTimer could even process the previous message. Bingo! That is the issue!
After further investigating the NAS code, it turns out that, although the previous scenario is possible, it actually does not queue sequentially. Incoming events are basically random when the host COM cannot handle the call. I could go very deeply here, but what happens is that, when the NAS COM event is called, the NAS actually checks to see if it is already handling another incoming event. If this is the case, it signals that it cannot process the incoming event (via a RPC_E_SERVERCALL_RETRYLATER) and COM basically waits "some time" before it retries the call. The problem is that this "some time" is not known and it changes, and that is when the trouble really starts.
Basically, what happened in our scenario was that 2 consecutive MessageReceived events will fire (before the first NTimer would) and obviously one GlobalVal would be lost and we would reply twice to a single event (the NTimers would fire, but with the same GlobalVal).
The cure was simple. When the MessageReceived event is fired, we process the information and reply to the event on the same connection. After all, ComCom objects do report back AL errors in XML format, so, in principle, there is no need to complicate matters.
So, after getting rid of the NTimer, and replying to the incoming request within the MessageReceived event, everything works as expected.
Jorge Alberto Torres (jtorres)Software Developer Engineer
I am pleased to announce the release of Jobs Update for Microsoft Dynamics NAV 5.0 SP1. This update is now available for you to download from Partner Source. Login credentials are required. https://mbs.microsoft.com/partnersource/downloads/releases/MicrosoftDynamicsNAV50SP1.htm
Jobs update rollup corrects the issues that are described in KB article number 954191.
Mtoo NorrildProgram Manager
For a table of platform updates and hotfix history for NAV 4 Sp3 with build numbers, update numbers and file contents, follow this link.
The E-Mail Logging feature is a service that offers users e-mail integration between Microsoft Outlook and Microsoft Dynamics NAV. This allows the user to maintain current e-mail records in both systems. It also gives the user the ability to share and publish knowledge about external contacts.
This is how it works: The e-mail dispatcher ("watchdog") monitors a specified mail folder, which is referred to as the Queue folder in this blog, on the Exchange Server. When an e-mail is retrieved from the Queue folder by the dispatcher, it is then placed in another folder – referred to as the Storage folder in this blog. The dispatcher logs the interaction in the Interaction Log Entry table in Navision. If the sender or the receiver is unknown to the system (no e-mail address is registered in the system), the e-mail will not be registered/logged in Navision and will not be stored in the queue or storage folder in Outlook. If the e-mail is marked with an option other than Normal, such as Private, Personal or Confidential, it will be deleted.There is a very old whitepaper that discusses this (Navision40_IntegrationwithOutlook_Technic.doc). It was written in the Exchange 5.5 days. This paper also discusses the way how to automate the Queue folder. Here is an extract from that paper:
There are several ways to get an e-mail copied to the Queue folder for further handling. The first method (Message Archival) involves using the E-Mail Logging feature on the Exchange server. In order to use the other methods they must be set up in each individual client Outlook installation. These methods offer various degrees of automatic logging.
· Message Archival. The Exchange Server can be set up to log all traffic and forward the e-mails to a specified folder or mailbox, which should then be used as the Queue folder. To configure the Exchange server to enable Message Archival, refer to the link below:
Exchange 2000 and Exchange Server 2003http://support.microsoft.com/support/kb/articles/Q261/1/73.ASP
· Setting Up Rules in Outlook. You can also set up rules in Outlook that are triggered by sending and/or receiving an e-mail. These rules are based on user-defined conditions. You can set up the rules to allow specific e-mails to be copied to the Queue folder. To ensure that all outgoing e-mails are placed in the Queue folder.
When you define these rules, make sure that they are the first rules that are applied so that other rules do not override them.
· Creating a Button. Another way to use the client to log your mail is to create a button you can click to have your e-mails copied automatically to the Queue folder. See the whitepaper for detailed instructions on how to create this button.· Setting Up an E-Mail Logging User. You can set up an individual user on the Exchange Server. Make sure the user’s Inbox is selected as the Queue folder. Other users can simply add this recipient as a “BCC” on outgoing e-mails that they want to log. Note that this only works for outgoing e-mails and should, therefore, be used in combination with the other methods described above.
One would expect this to work in Exchange 2007 the same way it worked in Exchange 2007. Well, there is news. Message Journaling in Exchange 2007 is much powerfull then it ever was. Good news you as a NAV admin would think. Well, there are many reasons why one would use Exchange 2007 Message Journaling over Exchange 2003 Message Archival. There is however one big reason for a NAV admin NOT to use is and that is that it breaks E-mail logging because of the following reasons: "It is all about security".
By default, all communication between computers running Exchange Server 2007 in the same Exchange organization is encrypted. This encryption includes journal reports. Exchange Server does a number of things to help reduce the risk of journal reports being tampered with: Secure links are used between Hub Transport servers and Mailbox servers in the Exchange 2007 organization.Journal reports are sent as "Microsoft Exchange" on behalf of the sender of the original message.Sessions between the Hub Transport server and Mailbox server are authenticated.Only authenticated connections are accepted when journal reports are sent between the Hub Transport servers and the Mailbox servers in the same Exchange 2007 organization.
The workaround is to create two Transport Rules. To do so, please start up Exchange Management Console, expand Organization Configuration, Hub Transport. On the left side pane of the screen, below Actions / Hub Transport, click on New Transport Rule. Follow the wizard and generate the conditions. For the Transport Rule to be effective for E-mail logging, you need to select "sent to users inside or outside the organization" and make sure it has Inside selected and when you create the second Transport Rule, you again need to select "sent to users inside or outside the organization" but then make sure it has the Outside selected. BCC the message to the Email logging account. Using BCC will copy just the message to the folder where it can be processed by the NAS as usual. By modifying the rules yet further you can reduce the set of messages copied to the folder so that the NAS is yet more efficient than it was using exchange 2003 message logging as the number of messages to parse can be easily reduced
This again makes the Exchange 2007 a far more better powerfull application then all other releases of Exchange Server!Marco Mels (mmels)Microsoft Dynamics NL
This post describes the simplest possible way to transform a form into a page in NAV 2009. Both Pages and Transformation is documented in more details elsewhere. Here, I just want to make the simples possible example, just to get a simple form transformed into a simple page.
You need to have at least a NAV 2009 classic client and the Transformation tool. To test the page, of course you also need the Rolebased client. But to just transform a form, you don't need it.
Import the tool:
1) Open a classic client, go to Object Designer and import the file TIF.fob from the folder TransformationTool\TIF Editor\2) Create a new form in NAV, as simple as possible. For example a Card form based on the customer table, with just a few fields on it. This is the form you want to transform.
Setup and use the Transformation tool:
3) Run form 177000 "Transformation Forms"
4) Click Import -> "Import PageType - FormType mapping", and select the file TransformationTool\TIF Editor\FormToPagetypeMapping.txt.
5) Click Functions -> Get Forms. Filter on Type = Form, and ID = the new form, then click OK. This gets the form(s) that you want to transform.6) In the FormType field, select "Card" ("Form with TabControl only and a source table").
Run the transformation:
7) Export the settings from form 177000: Click on Export -> "Transform Pages". You must export it to the TransformationTool folder, and it must be called TransformPages.xml.8) From Object Designer, export the form (Tools -> Export) as xml.You must export it to the folder TransformationTool, and it must be called Forms.xml.
You now have the form you want to transform, and the meta-data that tells the TranformationTool how to transform it.
9) Run the file FormTransformation.exe from the TransformationTool folder. This generates a new file called Pages.xml. It also logs any progress or errors in the file Transformation.log.
Import the new page:
10) Back in NAV (classic client): Go to Object Designer, and import the file Pages.xml, and then compile it.
If all steps ran without any errors, you have now transformed your form into a page which can be displayed in the rolebased client.
Please refer to this post about what I mean with "modern troubleshooting".
This post describes methods that work on any version of SQL Server, including SQL2000. It describes one of the most common questions I get, which is "Where do we start"...
General performance problems - where to start:If a system is suffering general performance problems, then it is not always easy to decide what to do first, or where to start. Then you may be tempted to collect lots of information, for example Profiler traces and databases which may or may not give any results, but which is guaranteed to require a lot of work both to collect, to send, and to analyse.
Often, over-indexing is one of the main causes of both bad performance problems and blocking. Indexes take time to maintain, and updating an index causes locks, which in turn can contribute to blocking-problems. so in a cases where the problem can't be located to a specific action, one place to start is to do some index tuning.
In a case like that, I often begin by asking for just two files:
Each of these files don't take long to prepare, and are normally small enough to send by email.
You collect the Excel spreadsheet like this:
When you get the spreadsheet, sort it by "No. of Records", or by "Size (KB)". The difference is, that "Size (KB)" includes the size of the indexes on each table. So either way of sorting gives you a good idea of which tables are being updated the most, and which tables have lots of both records and indexes.
Then load the NAV objects that you also received, and for the top 5 - 10 tob tables in the spreadsheet, take a look at the tables in NAV, and check the number of keys and SIFT-indexes. Some times you will immediately see that these tables have had a lot of keys added, and you should try to see if you can reduce the number of keys, using the key properties MaintainSQLIndex, MaintainSIFTIndex and SIFTLevelsToMaintain (remember the SIFTLevelsToMaintain-property don't exist any longer in NAV 5 SP1 where it was removed as part of re-designing the SIFT system).
Which indexes to disable the SQL-maintenance of:Only if you know how the system is being used, can you tell whether a certain index is being used or not. But, for example, a key like "IC Partner Code" in table 17 is only ever useful if the customer is using Intercompany Posting, and the "Additional-Currency Amount"-sumindex field on the same table is only needed if Additional currency is being used. So some times, a few obvious changes can be done. But to really do some index tuning, you need to know more than the objects alone can tell you.
You can also take the opposite approach, and disable maintenance of all indexes and SIFT (except for the clustered index). This will show you which ones are really needed when certain processes begin to run very slowly, and you will then have to (quickly) re-enable those. This is of course a risky approach, but it can be quicker than analyzing each individual key.
In deciding which indexes may be disabled, the following tools may help as well:If running on SQL Server 2005 or later, run the query "Index Usage" (follow this link)
The Key Information tool on the SQL Server Resource kit can help you deciding the cost of indexes per table, and help deciding the usefulness of SIFT indexes.With Navision Developers Tool (NDT), you can run "Where Used" on a key, to see in which object it is being used. If you use this method, then make sure to select everything in the "Where Used"-options. And keep in mind, that even with everyhthing selected, the NDT cannot see if users are manually specifying certain keys on the forms and reports they are running.
Lars Lohndorf-Larsen (Lohndorf)Escalation Engineer
Microsoft Dynamics NAV 5.0 SP1 introduces a new way to handle SIFT. Instead of maintaining totals in separate tables, Dynamics NAV 5.0 SP1 uses a SQL feature called indexed views. Indexed views will automatically be maintained by the SQL Server.
With SQL Server 2000, updating an indexed view can be a time consuming process as the SQL Server 2000 might decide to include a clustered index scan as part of its query plan to update the view. If your Microsoft Dynamics NAV implementation includes tables with many records and is based on Microsoft SQL Server 2000 there is a potential risk for experiencing bad performance.
Microsoft Dynamics NAV 5.0 SP1 is optimized for Microsoft SQL Server 2005 and you should consider to upgrade to SQL Server 2005 if you are implementing Microsoft Dynamics NAV 5.0 SP1.
The problem described here, only applies to SQL Server 2000. SQL Server 2005 handles the updates of indexed views much more efficiently.
I am pleased to announce the release of Upgrade toolkit for Microsoft Dynamics NAV 5.0 SP1. This update is now available for the first countries and it’s ready for you to download from Partner Source. Login credentials are required. https://mbs.microsoft.com/partnersource/downloads/releases/MicrosoftDynamicsNAV50SP1.htm
The Upgrade toolkit update rollup corrects the issues that are described in KB article number 952193.
Many NAV solutions, including internal ones, have the necessity to use .Net as a supplement of NAV technology, in order to complete their logic; however, dealing with managed and unmanaged world takes some extra challenges, especially when the managed code uses unmanaged resources. This is further important, when the .Net component will be hosted on the NAS, as it restarts (traditionally because of a deadlock) giving a short time for the unmanaged resources to be disposed.
When a .Net component ends, it is marked as to be released by the .Net runtime garbage collector, however, the time when the component will be freed from memory is not known (this is especially true for IDisposable objects). This can be problematic when the managed component is using unmanaged resources (such as TCP ports, files and the like), as these are not available to the host computer until they are completely de-referenced.
.Net architecture is aware of this issue, and has means to deal with it, this is further explained in the IDisposable Interface (http://msdn.microsoft.com/en-us/library/system.idisposable.aspx). What this document explains, is that your .Net component has to have the IDisposable interface in order to stop the unmanaged resources within your managed code. This works well, except that it adds the extra constrain that the Dispose method should be called specifically in order to trigger the logic, this is somehow a little bit tricky in NAV, as there is no specific method that is called on a codeunit, when it is exiting (there is no “OnStop” method).
There are at least two different ways to solve this problem. One is to create a mixed mode wrapper, and the other one is to call the Dispose (or Stop, or whatever you want to call your method) when the CompanyClose trigger is executed.
As an example, let’s assume that your solution needs to query the NAS for information using a TCP Socket. For that, you create a .Net COM component that will use the System.Net.Sockets.TcpClient object to be opened once the component starts, and you add this component to codeunit 50000. You modify codeunit 1 trigger 99 to start your single instance codeunit 50000. Everything seems to be working great, until the NAS restarts and your component refuses to start again (or does not start on the first restart try). The error is something like: “The TCP port x, is already in use”.
It might take some thinking before knowing exactly what went wrong over here, but it is easy to explain. As we mention before, when a .Net component is deleted, it is marked to be discarded by the .Net runtime at a later time (and if you still have references to your object, this time might be never), while the garbage collector “kicks in”, all unmanaged resources are still owned and opened by the previous component instance, preventing new instances on reusing the same unmanaged resource (in this example a TCP port).
The solution here is simple. We should add the Dispose method to the .Net component, and somehow call it when the single instance codeunit stops (on the “OnStop” event).
Now, where should we locate such a Dispose call? Since the NAS needs a company to work, we can use the OnCompanyClose trigger to further call our Stop method, which will call the Dispose method. We cannot only code this logic on the single instance codeunit (50000), as there is no trigger that will be called when the NAS is restarting.
Our hypothetical (and simplified) codeunit could look something like:
And one way to call the OnStop trigger would be:
There can be other ways to solve this problem (as we also pointed out, mixed mode code is another obvious option), but the key is to know when the .Net COM component should be discarded if this component is using unmanaged resources.
Jorge Alberto TorresSoftware Developer Engineer
Last month (23rd – 25th April), Claus Lundstrøm and I took to the road and drove all the way from Vedbæk to Netherlands and Belgium to meet one of our would-be TAP Partners and attend the launch of Belgian Dynamics Community respectively. The camaraderie and dedication of Dynamics enthusiasts in Belgium was exemplary and compelled me to write a blog entry here in our team blog. You can read a lot more details about it on Waldo’s blog post but I wanted to highlight some of our takeaways from this highly successful event.
Firstly I am reminded of my first ever Microsoft Windows NT Developers’ Conference back in 1992(!) here in Brussels, Belgium – anyone remember that? Belgium is an amazingly convenient place to get to, it has friendly people who speak multiple languages and are really glad to help you, to work with you and fast forward to 2008 this event was no exception! The event organizers had worked tirelessly at their own expense to put together the event, agenda, logistics and gather sponsors and by any measure the event was a sellout success. They registered over 250 participants and had over 200 show up despite traffic delays and Microsoft members being invited to Steve Ballmer 1:1 session the very same evening.
The event location was a picture perfect castle with cooperative weather despite some rain showers earlier. We got there for lunch, discussed logistics and parted ways in search of our hotel for the night stay (good thing we did that, as it took us nearly all the spare time we had before the event late evening to sort out mix-up with our booking and find the new hotel). By the time we came back, venue was transformed for the launch event, people were already arriving in hoards. The organizers provided meals, beverages, snacks, champagne, wine throughout the evening and kept all the participants happy. The keynote was presented by Marc Charlier who recently moved from SAP to lead Dynamics Marketing in Benelux region. I followed up with a high-level MBS Strategy / Roadmap presentation. A Coffee break followed where most audience were interested in future direction of NAV in relation to Managed Platform. I was very interested in hearing their opinions and surely got plentiful of it. Claus followed then with a detailed hands on demos of NAV 2009 product with focus on Page and Report design, customization and personalization. His usage of image fields to demo pages (with fact boxes) and interactive reports was extremely effective and audience were clearly impressed with the power and ease of use of NAV 2009.
Everyone seemed to know everyone else! It was very nice to see people mingling with one another, catching up on their projects, place of work, and life. Majority of attendees were Dynamics NAV enthusiasts but Dynamics CRM, & Dynamics AX had their followings too. What followed was a raffle and party where we received over-attention (signing away NAV books as stars) and a fare share of wining, dining and dancing till wee hours of the morning. If you would like to see pictures from the event follow this link.
Dynamics Community in Belgium is a shining example of what communities are all about - they are for the people, by the people who share a common interest. We at Microsoft are very thankful for this community’s interest in Dynamics NAV, it is an integral part of the entire echo system around MBS products as it helps nurture growth of our business organically by bringing like minded people together to share their experiences, ideas, & opinions, voice their concerns, collaborate on projects & network with one another. The Belgium Dynamics Community is off to a great start and I wish them successful years ahead.
- Naveen Garg
In previous versions, Microsoft Dynamics NAV maintains SIFT totals in SIFT tables. So updating the main table is done in one query. Updating the related SIFT tables is done by seperate queries run from triggers on the SQL tables. This makes it difficult to idenitfy the real cost of updating the table with a SQL Profiler trace, since you need to take several queries into account to get the real cost.
From NAV version 5 SP1, the SIFT tables are replaced with Indexed Views which makes it simpler to trace the full cost of an update to a base table and its associated indexed views:
In a SQL Profiler Trace, enable the event Performance:Showplan XML. With this event, when you see an update to a base table (for example INSERT INTO "W1500SP1"."dbo"."CRONUS International Ltd_$G_L Entry" etc), then the "Showplan XML"-event for this query will show not just the insert into the base table, but also which indexed views were updated, and the percentage of cost that each indexed view added to the whole query. So with this event you will have the full cost of an update and associated SIFT indexes in just one place - not spread over multiple queries in the Profiler trace.
You can read more details and screenshots of this, and other changed in NAV 5 SP1 in this post:
Changes to Microsoft Dynamics NAV 5.0 SP1 with Microsoft SQL Server
Lars Lohndorf-Larsen (Lohndorf)Escalation Engineer
When running forms like Customer (Vendor) Ledger Entries and Apply Customer(Vendor) Ledger Entries, and selecting: send-to Excel, the following error occurs if customer (vendor) name contains character '/':
Problems came up in the following areas during load:
Workbook setting ....
To correct this issue, open the style sheet file in notepad, default file is NavisionFormToExcel, placed in Stylesheet folder of the Client folder. Browse to the following section and replace the marked line :
<xsl:template match="Control[@type='TableBox']"> <Worksheet xmlns="urn:schemas-microsoft-com:office:spreadsheet"> <xsl:attribute name="ss:Name"> <xsl:variable name="TableBoxCaption"> <xsl:value-of select="//Object/@caption"/> <!-- replace this line !--> </xsl:variable>
Then browse to the following section and replace the section:
<xsl:template match="Control[@type='Frame']"> <Worksheet xmlns="urn:schemas-microsoft-com:office:spreadsheet"> <xsl:attribute name="ss:Name"> <xsl:value-of select="@caption"/> <!--changed line!--> <xsl:if test="@caption = ''"> <xsl:variable name="TableBoxCaption"> <xsl:value-of select="//Object/@caption"/> <!--changed line!--> </xsl:variable>
<xsl:template match="Control[@type='Frame']"> <Worksheet xmlns="urn:schemas-microsoft-com:office:spreadsheet"> <xsl:attribute name="ss:Name"> <xsl:value-of select="translate(@caption,'\/:*?>|','')"/> <!--changed line!--> <xsl:if test="@caption = ''"> <xsl:variable name="TableBoxCaption"> <xsl:value-of select="translate(//Object/@caption,'\/:*?>|','')"/> <!--changed line!--> </xsl:variable>
In C/Front for Microsoft Dynamics NAV Version 5 SP1, it is no longer possible to initialise it in the usual way from Visual Basic. Often you would initialise C/Front like this:
CFR = New Microsoft.Navision.CFront.CFrontDotNet
But with SP1, this syntax will give you the following error in Visual Studio:
Error 1 'Microsoft.Navision.CFront.CFrontDotNet.Private Sub New()' is not accessible in this context because it is 'Private'.
This way to initialise C/Front was removed because there were various problems (mainly with memory corruption) when disposing C/Front. So to stabilise it, the public constructor of CFrontDotNet was removed. Now, initialise it like this instead:
CFR = Microsoft.Navision.CFront.CFrontDotNet.Instance
Lars Lohndorf-Larsen (Lohndorf)