NAV Text Object Handler

AdministratorAdministrator Member, Moderator, Administrator Posts: 2,500
edited 2013-05-13 in Download section
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.
«1

Comments

  • JDVyskaJDVyska Member Posts: 179
    I'll be happy to discuss any details or provide source. I'm hoping folks can get really creative with this in the area of version control... whether linking to VCS or building an 'in NAV' VCS.

    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.
    JEREMY VYSKA
    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"
  • kinekine Member Posts: 12,562
    Thanks for that. I never had enough time to make something like that even when I read the blog few weeks ago. I will try when I had time.

    For now one question: is it working correctly when I have more NAV clients opened on my PC?
    Kamil Sacek
    MVP - Dynamics NAV
    My BLOG
    NAVERTICA a.s.
  • SNielsenSNielsen Member Posts: 37
    Right now it will grab the first NAV instance from the Running Object Table, so no it does not support multiple running NAV versions at the same time.

    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.
  • PureHeartPureHeart Member Posts: 190
    Kine,
    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 :wink:
    Why don't you try my compare tool?
    http://www.mibuso.com/dlinfo.asp?FileID=1123
  • JDVyskaJDVyska Member Posts: 179
    Unfortunately, I've been told about and discovered a particularly challenging item: In the text export, the dll writes not the object name in the first line! It writes the object caption.

    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:
    OBJECT Form 50000 My Awesome Form
    


    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.
    JEREMY VYSKA
    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"
  • MatthiasKönigMatthiasKönig Member Posts: 14
    no problem JDVyska ;)

    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 :)
  • janpieterjanpieter Member Posts: 298
    Hello!

    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:
            public ObjectDesigner(String CompanyName)
            {
                Guid guid = new Guid("50000004-0000-1000-0001-0000836BD2D2");
                Hashtable runningObjects = GetActiveObjectList(DefaultMonikerName);
    
                foreach (DictionaryEntry de in runningObjects)
                {
                    string progId = de.Key.ToString();
                    if (progId.IndexOf("{") != -1)
                    {
                        // Convert a class id into a friendly prog Id
                        progId = ConvertClassIdToProgId(de.Key.ToString());
                    }
                    
                    if (progId.EndsWith(CompanyName))
                    {
                        object getObj = GetActiveObject(progId);
                        if (getObj != null)
                        {
                            this._objectDesigner = getObj as IObjectDesigner;
                            break;
                        }
                        else
                        {
                            throw new Exception("Could not connect to Dynamics NAV " + progId);
                        }
                    }
                }
    
                if (this._objectDesigner == null)
                {
                    throw new Exception("Could not find a Dynamics NAV instance with companyname " + CompanyName );
                }
            }
    

    And the wrapper class wich is exposed to COM (Navision) contains this function:
            public void GetNavisionObject(int ObjectType, int ObjectID, string ObjectName, string CompanyName, string FileName)
            {
                //Codeunit = 5,
                //Dataport = 4,
                //Form = 2,
                //Report = 3,
                //Table = 1
                if (System.IO.File.Exists(FileName))
                    System.IO.File.Delete(FileName);
    
                System.IO.FileStream fs;            
                System.IO.MemoryStream ob;
                ObjectDesigner od = new ObjectDesigner(CompanyName);
                ob = od.ReadObjectToStream((NavObjectType)ObjectType, ObjectID);
    
                fs = new System.IO.FileStream(FileName, System.IO.FileMode.OpenOrCreate);
                ob.WriteTo(fs);
                
                fs.Close();
                fs.Dispose();
                fs = null;
    
                ob.Dispose();
                ob = null;
    
                od = null;
            }
    

    I bet it is not necesarry to explain what parameters should be put into the function from Navision ;)
    In a world without Borders or Fences, who needs Windows and Gates?
  • PureHeartPureHeart Member Posts: 190
    Hello Hello!
    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.
                        if (displayName.IndexOf(dbname) != -1 &&
                            displayName.IndexOf(dbcompanyname) != -1)
    
    Why don't you try my compare tool?
    http://www.mibuso.com/dlinfo.asp?FileID=1123
  • janpieterjanpieter Member Posts: 298
    Hello me again!

    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.
            private unsafe MemoryStream ToMemoryStream(IStream comStream, string ObjectName, string YesValue, string NoValue)
            {
                bool bFirst = true;
    
                MemoryStream stream = new MemoryStream();
                byte[] pv = new byte[100];
                uint num = 0;
                IntPtr pcbRead = new IntPtr((void*) &num);
                comStream.Seek((long) 0, 0, IntPtr.Zero);
    
                do
                {
                    num = 0;
                    comStream.Read(pv, pv.Length, pcbRead);
    
                    // start - this part replaces object caption with object name
                    // modify first line of file
                    if (bFirst)
                    {
                        System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding(); 
                        string strFilePart = enc.GetString(pv);
    
                        char[] splitter = { '\r' };
                        char[] splitter2 = { ' ' };
                        
                        string[] arSplitted = new string[20];
                        string[] arSplitted2 = new string[20];
    
                        arSplitted = strFilePart.Split(splitter);
                        arSplitted2 = arSplitted[0].Split(splitter2);
    
                        arSplitted[0] = arSplitted2[0] + " " + arSplitted2[1] + " " + arSplitted2[2] + " " + ObjectName;
                        strFilePart = string.Join("\r", arSplitted);
    
                        num = (uint)strFilePart.Length;
                        pv = enc.GetBytes(strFilePart);
                        bFirst = false;
                    }
                    // end - this part replaces object caption with object name
    
                    stream.Write(pv, 0, (int) num);
                }
                while (num > 0);
    
                // start - this part replaces local yes and no attributes with yes and no ENU captions
                string s = System.Text.Encoding.Default.GetString(stream.GetBuffer(), 0, (int)stream.Length);
                s = s.Replace("=" + YesValue + " }", "=Yes }");
                s = s.Replace("=" + YesValue + ";", "=Yes;");
                s = s.Replace("CONST(" + YesValue + ")", "CONST(Yes)");
                s = s.Replace("FILTER(" + YesValue + ")", "FILTER(Yes)");
                s = s.Replace("=" + NoValue + " }", "=No }");
                s = s.Replace("=" + NoValue + ";", "=No;");
                s = s.Replace("CONST(" + NoValue + ")", "CONST(No)");
                s = s.Replace("FILTER(" + NoValue + ")", "FILTER(No)");
    
                System.Text.UTF8Encoding utf8Encoding = new System.Text.UTF8Encoding();
                stream = new MemoryStream(utf8Encoding.GetBytes(s));  
                // end - this part replaces local yes and no attributes with yes and no ENU captions
    
                return stream;
            }
    

    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
    CREATE(lclsAutoNavisionTextExport);                     
    
    lrecObject.RESET;
    lrecObject.SETRANGE(ID, 1, 10);
    lrecObject.SETRANGE(Type, lrecObject.Type::Table, lrecObject.Type::Codeunit);
    IF lrecObject.FIND('-') THEN
    BEGIN
      REPEAT
        lclsAutoNavisionTextExport.GetNavisionObject(lrecObject.Type,
                                                     lrecObject.ID,
                                                     lrecObject.Name,
                                                     COMPANYNAME,
                                                     'c:\' + FORMAT(lrecObject.Type) + '_' + FORMAT(lrecObject.ID) + '.txt',
                                                     FORMAT(TRUE),
                                                     FORMAT(FALSE));
      UNTIL lrecObject.NEXT = 0;
    END;
    

    Have fun with this ;)
    In a world without Borders or Fences, who needs Windows and Gates?
  • JDVyskaJDVyska Member Posts: 179
    Interesting...

    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!
    JEREMY VYSKA
    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"
  • PureHeartPureHeart Member Posts: 190
    janpieter the problem is that if you have more than one fdb opened with the same company name the dll will fail to recognize the correct instance of Navision...Intestead having the db name (could be a setup name...) will allow you to select the correct Instance! :mrgreen:
    Why don't you try my compare tool?
    http://www.mibuso.com/dlinfo.asp?FileID=1123
  • janpieterjanpieter Member Posts: 298
    JDVyska,

    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 :mrgreen:

    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.
    In a world without Borders or Fences, who needs Windows and Gates?
  • janpieterjanpieter Member Posts: 298
    I've worked out a thought about how to get a fool-proof reference to the calling navision client without relying on the company name which isn't unique.

    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?
    In a world without Borders or Fences, who needs Windows and Gates?
  • JDVyskaJDVyska Member Posts: 179
    One of my coworkers claims to have figured out a way. He's been going full tilt on that for a while, since he is envisioning ways to massively improve the toolset to help speed upgrades and such.

    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.
    JEREMY VYSKA
    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"
  • janpieterjanpieter Member Posts: 298
    JDVyska wrote:
    One of my coworkers claims to have figured out a way. He's been going full tilt on that for a while, since he is envisioning ways to massively improve the toolset to help speed upgrades and such.

    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.


    I'm also envisioning ways not to just improve upgrades; also doing full automated checks on sources etc., maybe even auto documentation futures :D
    I'm curious which way your coworker thinks to tackle this ... Please demand him/her to share [-o<
    In a world without Borders or Fences, who needs Windows and Gates?
  • SNielsenSNielsen Member Posts: 37
    Hot thread!

    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...
  • janpieterjanpieter Member Posts: 298
    Aaargh SNielsen,

    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 !
        lclsAutoNavisionTextExport.GetNavisionObject(lrecObject.Type, 
                                                     lrecObject.ID, 
                                                     lrecObject.Name,
                                                     COPYSTR(CONTEXTURL, 1, STRPOS(CONTEXTURL, 'servertype') - 2),
                                                     'c:\test.txt',
                                                     FORMAT(TRUE),
                                                     FORMAT(FALSE));
    
    In a world without Borders or Fences, who needs Windows and Gates?
  • jonwlongjonwlong Member Posts: 11
    I'm the coworker Jeremy is referring to above.

    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
    Jon Long - ArcherPoint
    MCP - Dynamics NAV
  • janpieterjanpieter Member Posts: 298
    Hello Jon,

    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.
    In a world without Borders or Fences, who needs Windows and Gates?
  • jonwlongjonwlong Member Posts: 11
    I don't want it to be absolutely fileless. It would depend. The functionality in my architecture allows for getting objects directly from a NAV db, or text files and potentially directly from VSS. So, a file is not necessarily required. i.e., Querying 3 databases(old base, custom, new base) for compare purposes to determine what objects need to be manually merged. This may only result in a handfull of objects that would need to be exported as text to files and some objects imported directly from custom into new db without the need for a text file.
    Jon Long - ArcherPoint
    MCP - Dynamics NAV
  • jonwlongjonwlong Member Posts: 11
    Danger Will Rodgers!(Re:NAV Text Object Handler(NOH))

    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?
    Jon Long - ArcherPoint
    MCP - Dynamics NAV
  • SNielsenSNielsen Member Posts: 37
    In table 5054 Contact Business Relation field 3 "Link to Table" is a option field :-). It does not refer to a DATABASE::"4".
  • SNielsenSNielsen Member Posts: 37
    The other issue is probably just related to encoding, i think that can be handled in the automation itself.
  • janpieterjanpieter Member Posts: 298
    The object name problem i've solved earlier in this thread, as well as yes/no ENU captions that are also localized (dutch 'ja' 'nee'). I do this by passing the object name and the format(true) and format(false) parameters to the DLL, which then converts the text file.

    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.
    In a world without Borders or Fences, who needs Windows and Gates?
  • MatthiasKönigMatthiasKönig Member Posts: 14
    where can i download the "fixed" file? or must i code this by my self? That would be pity...
  • zeonzeon Member Posts: 130
    Very nice app!

    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
  • janpieterjanpieter Member Posts: 298
    zeon wrote:
    Very nice app!

    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.
    public void GetObject(string ContextURL, int ObjectType, int ObjectID, string ObjectName, string FileName, string YesValue, string NoValue)
            {
                if (File.Exists(FileName))
                    File.Delete(FileName);
    

    Just PM your mail adress if you want source project.
    In a world without Borders or Fences, who needs Windows and Gates?
  • zeonzeon Member Posts: 130
    Well, I have tested this a bit more in conjuction with version control system Tortoise SVN.

    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
  • gerdhuebnergerdhuebner Member Posts: 155
    Hi guys,
    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?
  • gerdhuebnergerdhuebner Member Posts: 155
    There is a workaround for the "object caption problem", which does not require language specific manipulation of the stream data. It seems to be that the problem is due only to the method
    int ReadObject([In] int objectType, [In] int objectId, [In] IStream destination);
    
    If you use, instead, the similar method
    int ReadObjects([In] String filter, [In] IStream destination);
    
    from the INSObjectDesigner interface,
    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
    ReadObject(1, 3, destination);
    
    the equivalent call would be
    ReadObjects("WHERE(Type=CONST(Table),ID=CONST(3))", destination);
    
Sign In or Register to comment.