NAV Text Object Handler
This download is a poorly written (I don't know C# at all) DLL file that exposes Søren's ability to Import From / Export To text files directly to NAV via Automation.
This would absolutely not be possible but for the wonderful work of Søren Nielsen, provided freely to the community on his blog,
http://www.gotcal.com.
See the included example FOB for usage. Very bare-bones, but anyone who wants this can certainly make use of it.
To make use of this DLL (which is a .NET DLL), you'll have to use the included installation batch file, which relies on 'regasm' from the v2.0.050727 .NET Framework, typically located in C:\Windows\Microsoft.NET\Framework. You *must* run this in the same directory as the NAV Client or you'll get errors when attempting to use.
http://www.mibuso.com/dlinfo.asp?FileID=1012
Discuss this download here.
Comments
As for the code that accesses the NAV object tables? All came from http://gotcal.com/ - particularly this post. Søren explains how he managed it using the Running Object Table in this post. Thanks Søren!
Also thanks to Luc for putting up with a small array of emails trying to make it portable and safe to upload
Edit: I should clarify: I've tested this only with 5.0 and 5.0 SP1. I cannot answer to it working for earlier versions, and I'll try to test it with 2009 sometime later this week.
CEO, Spare Brained Ideas, Göteborg, Sweden
New (April 2021) Getting Started with Microsoft Dynamics 365 Business Central Book Available: "Your First 20 Hours with Business Central"
For now one question: is it working correctly when I have more NAV clients opened on my PC?
MVP - Dynamics NAV
My BLOG
NAVERTICA a.s.
I have an example for a all object exporter that queries the user like the Developers Toolkit does, so you can select what NAV client to export objects from (check the blog during this coming week).
Another interesting thing, is it allows you to extract objects to text without the use of a developer license! For importing though it honors the permissions, and throws a:
"HRESULT = 0x8004005 : You do not have permission to run the 'File, Import, Text' System"
But it will give end users access to do some object comparison, and version management. When we get a tool together for it.
Soren
http://gotcal.com
Based on the code of Søren Nielsen I've modified the functions to input also the instance of Navision to read so you'll be able to select the database and the company when you are calling the export function.
If you are interested I can explain in more detail what I did.
Søren,
Thank you so much again, Do you know if it would be possible to extract objects with NAS?
I'm trying with no success even if I leave a Navision Client opened...
Any Idea?
Thanks
http://www.mibuso.com/dlinfo.asp?FileID=1123
So, for example, if you have Form 50000 - Something Card and you set the form's caption to "My Awesome Form", the first line of the file would read:
I'm not sure if Søren will be able to help that, but I might able able to re-write the Export routine in the DLL to do a little post-processing fix to that item.
The other issue (thanks Matthias!) is that it uses local language strings, like german 'Ja' instead of 'Yes'. I might be able to do something clever with .stx files, but likely not anytime this week.
CEO, Spare Brained Ideas, Göteborg, Sweden
New (April 2021) Getting Started with Microsoft Dynamics 365 Business Central Book Available: "Your First 20 Hours with Business Central"
a little workaround: use this DLL with a Report and change the language... but this is not the fine way.
if there is an update, i will be happy to get this information
Thanks for the great idea! Good to see that we finally we can extract txt files automatically from Navision. I have been searching for this sollution. I knew there had to be a way because the developer tool was doing the same thing as well! Great job for everyone involved! =D>
So with this lead you gave me i dove into the problem a bit more. I rewrote some functions to share with you all; maybe you can improve your own software with it.
I added a companyname paramter to the objectdesinger class constructor. Since you can get the companyname with the COMPANYNAME instruction in Navision, this is the best way you can automatically select the database from where the DLL call is made. This is 100% foolproof unless you have multiple databases open with the same database name! (wich may occur maybe in upgrade projects)
Hopefully not too many bugs; i don't have a lot of time though this was too interesting to leave for weeks :P
ObjectDesigner class constructor rewrite:
And the wrapper class wich is exposed to COM (Navision) contains this function:
I bet it is not necesarry to explain what parameters should be put into the function from Navision
I've also added as parameter the database name so you will be able from Navision to select the correct database and company (we could also add the SQL server).
Using the Database table you'll know the databse name if you are in SQL.
Modifing the function GetActiveObject you can return directly the object that you want without looping them later.
In the test of the GetActiveObject I've added the following code and then removed the for loop in the ObjectDesigner.
http://www.mibuso.com/dlinfo.asp?FileID=1123
Pureheart i don't think your code would be convinient in our case we commonly use local copies (just fdb file format) on our harddisk. I gues you won't be able to retrieve databasename from these navision instances? Although thanks for the input.
I have been working on the object caption / object name and yes/no local issue and came up with the following sollution wich is 99% secure. Only when you create a constant variable wich uses simular characters as the replaced strings the code might replace too much. I gues strings like '=Ja }' are not used in constant variable.
I replaced the ToMemoryStream function in the objectdesginer class with the following code. This code will create importable object text files for me. It returns an adjusted memorystream. When you save it all dutch and german 'Ja' strings will be converted to 'Yes' and the object caption is replaced with the object name.
To provide this function with the proper parameters use this code in navision and create the com wrapper function with these parameters. Should work for all countries like this..!
code exports first 10 of every navision 3.70 objects
Have fun with this
I'll incorporate some of the proposed changes from this thread into a new release this weekend. I'll probably take jan's clever yes/no fix and make that a separate function call for multilingual uses, just to make the function calls simpler for most folks. Or I may create a codeunit wrapper to ease function calls to require minimal parameters. One of the two (or maybe both, since the target audience is developers, naturally).
Thanks for all the continuing development!
CEO, Spare Brained Ideas, Göteborg, Sweden
New (April 2021) Getting Started with Microsoft Dynamics 365 Business Central Book Available: "Your First 20 Hours with Business Central"
http://www.mibuso.com/dlinfo.asp?FileID=1123
If you like i can send you my VS 2005 project. Just PM your e-mail. I forgot to mention that i somehow didn't get your application to work; it just crashes when you call the function.
Since it is not a big deal; i recreated the C# wrapper anyway, because i also like to fool arround with it
Purheart,
You are absolutely right; when i think it over it is too poor to rely only on companyname. Happens often that you work on a live database and a testdatabase who share the same companyname. And that is waiting for a disaster to happen, where everyone is blindly relying on version management software using this system.
A setup entry is a lot better; though i still find it is not perfect as databases are being copied.
I will keep thinking. I have a way to get the window handles of the current used navision session; maybe i'll find a way to extract preciser information about the used client process using those handles.
I was thinking of creating a mostly empty dummy object in Navision with an unique code hidden in the tablename just before calling the DLL. In the DLL we can read this object first and compare it's unique value with the value passed into the function from navision. When it matches, then we know we have the current session.
Now i wouldnt rely on the randomizer function to generate an unique number. I don't think the randomizer is random at all. The hwnd definitly is unique i have a VB6 function that successfully retrieves the current window handle. This is a way that can work although i should convert this function to C#.
Maybe there is a better way. Any thoughts?? Any navision command i can use to generate some string that is unique for every session you have opened??
Maybe other thoughts on this issue you may want to share?
Hopefully he'll be sharing that to me soon. He also split up the DLL a few ways to make it more well-designed. The COM interface becomes just an interface to the DLL, some other odds and ends like that.
CEO, Spare Brained Ideas, Göteborg, Sweden
New (April 2021) Getting Started with Microsoft Dynamics 365 Business Central Book Available: "Your First 20 Hours with Business Central"
I'm also envisioning ways not to just improve upgrades; also doing full automated checks on sources etc., maybe even auto documentation futures
I'm curious which way your coworker thinks to tackle this ... Please demand him/her to share [-o<
There are ways to control how get the right "session", as the ROT also returns you a name, similar to the CONTEXTURL. If you look at this: http://www.codeproject.com/KB/cs/automa ... tudio.aspx im sure you can get some inspiration on it. It is a VS2003 project.
Im finishing up a project that handles it, i will post it shortly on my blog www.gotcal.com.
Lets join forces and collaborate on the shared goal...
Soren
http://gotcal.com
You're a genius; i feel so stupid, not knowing the contexturl function (with 6 years in navision experience)!
ContextURL is indeed almost exactly what you find in the progid!
In fact you can replace the companyname parameter in my previous examle and fill it with the contexturl and that would almost works by itself. The only thing you have to do is remove the '&Servertype=.....' part at the end of the contexturl string, this part is not in the ProgID.
That should definitely work and is easy to implement. Many thanks!
edit:
My calling function from navision now looks like this, and it works !
My original motivation was to minimize grunt work in upgrades by automating what can be automated. Adding Søren's code to NAVObjectHandler has been a huge step forward for me. Thanks Søren!
I prefer to separate the complexity in the NAVObjectHandler from the COM object. So, I created a simple COM object which only includes the necessary interface(s), i.e., Save(Split). This COM references NAVFileReader(.Net dll) which I wrote a while back which performs upgrade/search/save to file actions on NAV objects. NAVFileReader then references NAVObjectHandler. So, I'm treating NAVObjectHandler simply as a mechanical method to get objects out of and into NAV without the need for files(filelessly). It does not need to do anything else. Once it renders the object to a MemoryStream, the MemoryStream can be passed onto any other application for any other tasks. File splitting for example should be in another dll or class library. NAVObjectHandler will(should) likely remain fairly static. By removing it from the COM dll, it theoretically has no dependencies outside of itself. It should be closed for modification.
My point is that the NAVFileReader level is infinitely extended with functionality, i.e., Source Control Integration, Upgrade Automation, Documentation Automation, Logging, Code Sharing etc...
I'm currently obsessing with remote client object access(i.e., outside the domain). It is most important to me for the client to communicate with a central server, not necessarily the other way around. My idea is streamlined upgrade functionality for highly customized clients, integrated VSS management for developers(Jeremy is working on this) and auto client upgrades for simple client db's. With NAVFileReader and NAVObjectHandler, all can be done filelessly and directly from a NAV client, thanks again, to Søren's code.
To overcome the challenges of remote client I/O, I'm currently considering Sockets via NAS and/or ".Net Remoting".
Sockets:
Pros: Can pass simple strings easily to and from an open socket. Probably will be used if we just need to get high level object info(VSS stuff for example). It's super fast. i.e., GetObjectVer("OType,OID") returns "NAVNA5.00,SER5.00" from remote db instantaneously(tested on COM, exe and Web). Does not require IIS.
Cons: I got into memory trouble when passing whole objects as string and NAV InStream.WriteText function didn't work as expected on the IDispatch message. So comparing objects is out comparing local objects to objects in a remote computer via Sockets.
Remoting:
Pros: Application can cross domain. Can pass complex objects across domain via tcp stream(i.e.,NAVObject or NAVObjectList(generics) with several objects). Powerfull way to extend an application. I really think this is the way to go.
Cons: Need to expose the server(not client or Dev) ip on a machine where the NAV db is accessible. Requires IIS.
Jon
MCP - Dynamics NAV
We are using sockets to send the BLOB object to sourcesafe. Programmed in VB6. Between navision and Sourcesafe i wrote 2 components. Since sourcesafe doesn't support TCP interfacing i wrote 1 DLL as an interface to navision, and a server application as an interface to sourcesafe. This DLL and server application communicate with each other with TCP/IP sockets (VB6) and acts between Navision and Sourcesafe.
This works like a charm, even when you are on remote customer locations. I'm personally not into importing the text files. This in my believe does not really have advantages. Importing a binary BLOB object into the object table is treated like importing a FOB, except that the object properties (date / version / name) are not adjusted, but you can work arround that easally. Sourcesafe also accepts these binary BLOB files.
Our Version Management system (sorry can't publish it) is based on putting as much functionality as possible into C/AL code. Only shortcommings of navision are programmed in the DLL. What i've build so far into VB6 DLL's is:
- place navision form out of MDI window, so it is constantly visible.
- retreive window handles of Navision, the object designer, current active form, the MDI background
- receive window events (like resizing WM_SIZE)
- DLL that monitor's designer windows to be openend. It is sending automation event triggers to navision everytime you hit the design key in the object desinger or CTRL-F2 in a navision object. Also it sends an event when this designed object is closed. .
- source safe client module
- TCP communication module (not exposed to navision)
- (C#) and last but not least, the missing link: this text export i'm now implementing
My current ideas for the text export are:
- easy version comparing (select 2 versions of 1 object, download object and quickly compare those 2 objects.
- check if documentation (trigger) is filled correctly (should find a date formatted as today)
- check if all M/L captions are filled
- any other programming constraints
These checks can be performed when a designer window is closed. (we get this event from the designer window monitor DLL). After saving an object it can be exported, and a C/AL routine can open the object and do the clever checks and report the results to the developer. When developer accepts or corrects the errors he will be able to checkin the object into sourcesafe.
So with all of this; all what was interesting to us is the COM DLL where i can export txt objects from C/AL code. Not totally parallel on what you are doing.
Why do you absolutely want it to be filelessly?
Agreed sockets seem to be not verry reliable when sending large packets. Remember also problems with some routers. The sollution is to chunck the communication into peices.
MCP - Dynamics NAV
Captions in general seem to be a bit funky.
EX 1:
FRC=S‚ries de nø; (Normal Export)
FRC=S�ries de n�; (NOH Export)
EX 2:
Type::Company: (Normal Export)
Type::Organization:(NOH Export)
Even more disturbing is this line of code:
EX 3:
ContBusRel."Link to Table"::Employee: BEGIN (Normal Export)
ContBusRel."Link to Table"::"4": BEGIN (NOH Export)
Instead of Employee, it’s “4”. 4 is the Currency table. Not sure what the logic is there.
The caption as the object name has already been mentioned. Has anyone found a fix for this?
MCP - Dynamics NAV
Soren
http://gotcal.com
Soren
http://gotcal.com
The option captions you are getting are pretty nasty and probably makes the file not suitable for importing again. That's not good. Conversion routines are a challenge to write and where do the problems end?
This backs me up in not using the txt export for version management, and stick with the object BLOB export to store different objects automatically.
Although i'm still enthousiastic about the posibility for text export, it is still suitable for comparing versions, and automated code checks.
BUT, when I export an object to the same directory several times, the textfile is not replaced with the new export. In stead the new object is added to the original textfile now containing two objects in the same text file.
Can anyone confirm the same error?
Can anyone pm me the project source code?
/zeon
i don't have this problem.
I delete the file before extracting.
Just PM your mail adress if you want source project.
The problem I experience is that when the same object text file exists on disk as the one I'm exporting from NAV the new file will just be added to the first file, now containing to object text files in one.
If I delete the file prior to export it also gives problems (at least when using with SVN).
If I manually delete the file (e.g Table18.txt) on disk prior to exporting the same text file from NAV, SVN will not discover that the newly exported file differ from the one in the SVN repository.
So, the solution must be to REPLACE the original file when exporting a new one from NAV - else SVN will not discover the changes.
/zeon
I really appreciate your work about object extraction from NAV and there will be many interesting applications for it.
My focus is on another topic at the moment, and perhaps one of you can find the answer, because he encountered it already during his work:
Is it possible to extract some other informations of the running NAV session, for example the no. of sessions or the license key ?
Has anybody got an idea or even knows a method to call?
the object(s) are exactly exported as with the standard text export from a NAV object designer.
For example, if you want to read Table 3 with the equivalent call would be