Hi
For this pojeckt am I using NAV 2009 SP1.
I want to upload all files in a folder into nav. In classic this works fine but now I want to use rtc...
I can get rtc to upload a file but I always have to choose my file first. (I don't want to do that)
Is there a way to upload every file in the folder without asking anything of the user?
like this in classic
InFile.SETRANGE(Path, SalesSetup."My File Folder" + '\');
InFile.SETRANGE("Is a file", TRUE);
IF InFile.FINDSET THEN BEGIN
// here some code for taking care of the textfile...
REPEAT UNTIL InFile.NEXT=0;
0
Answers
do you happen to have an example or link to look at how to use this automation?
Look for azwierzchowski reply.
There was also a solution for RTC if you have 2009 R2, unfortunately we are using 2009 sp1
The program stops on the line
LautFolder := LautFileSystemObject.GetFolder(MyFolder);
http://msdn.microsoft.com/en-us/library/dd355255.aspx
-Mohana
http://mohana-dynamicsnav.blogspot.in/
https://www.facebook.com/MohanaDynamicsNav
If I try to run it in RTC I got the following error: Could not compile assembly...
I have commented out code and it run fine if I comment out these two lines
WHSFile := FilesCol.Item(i);
ltxtFileName := WHSFolder.Path + '\' + WHSFile.Name;
Any ideas?
Here is my code:
IF ISCLEAR(WHSFileSystemObject) THEN
CREATE(WHSFileSystemObject,TRUE,TRUE);
// If the folder does not exist, exit
IF NOT WHSFileSystemObject.FolderExists(MyFolder) THEN BEGIN
CLEAR(WHSFileSystemObject);
EXIT;
END;
WHSFolder := WHSFileSystemObject.GetFolder(MyFolder);
WHSFiles := WHSFolder.Files;
IF ISCLEAR(FilesCol) THEN
CREATE(FilesCol,TRUE,TRUE);
// ========================================================================
// Use a VBScript to fill a 'Microsoft Scripting Runtime'.Dictionary
IF ISCLEAR(Script) THEN
CREATE(Script,TRUE,TRUE);
Script.Language := 'VBScript';
//variable LautFolders is visible in script as FoldersByName
Script.AddObject('FilesByName', WHSFiles);
//variable FoldersCol is visible in script as FoldersById
Script.AddObject('FilesById', FilesCol);
//copy objects using VBScript
txtCR := '';
txtCR[1] := 13;
txtcode :=
'dim f1' + txtCR +
'For Each f1 in FilesByName' + txtCR +
' FilesById.Add (FilesById.Count+1), f1' + txtCR +
'Next' + txtCR;
Script.ExecuteStatement(txtcode);
CLEAR(Script);
// ========================================================================
FileCount := FilesCol.Count();
FOR FileInt := 1 TO FileCount DO BEGIN
WHSFile := FilesCol.Item(i); <---- Here is the problem!
ltxtFileName := WHSFolder.Path + '\' + WHSFile.Name;
// ==========================
// Here you do what you want to do with the file...
// MESSAGE(ltxtFileName);
// ==========================
END;
CLEAR(FilesCol);
CLEAR(WHSFileSystemObject);
Can you please post c# assembly? I think c/al -> c# translator messing up with your code. Would be interesting to see how this looks in c#.
I don't know how to do that :oops:
after first client run somewhere under "C:\ProgramData\Microsoft\Microsoft Dynamics NAV\60\Server\MicrosoftDynamicsNavServer\source\" on server machine you will find c# files for each object.
sing System;
using Microsoft.Dynamics.Nav.Runtime;
using Microsoft.Dynamics.Nav.Types;
using Microsoft.Dynamics.Nav.Types.Exceptions;
using Microsoft.Dynamics.Nav.Common.Language;
namespace Microsoft.Dynamics.Nav.BusinessApplication
{
//Travel Management
public sealed class Codeunit50000 : NavCodeunit
{
#region Non-user code (Declarations, constructors, properties)
#line hidden
private NavRecordHandle salesSetup;
private NavRecordHandle inFile1;
private NavFile inFile = null;
private NavText line = NavText.Default(500);
private NavArray<NavText> lineField;
private NavCode lineID = NavCode.Default(10);
private Int32 nextnr = 0;
private Int32 nextLineno = 0;
private Int32 delimeterplace = 0;
private Int32 fileLen = 0;
private NavXmlPortHandle importXMLPort;
public Codeunit50000(ITreeObject parent) : base(parent, 50000)
{
InitializeComponent();
}
private NavFile PInFile
{
get
{
if(inFile==null)
{
inFile = new NavFile(this);
}
return (inFile);
}
set
{
inFile = value;
}
}
#line default
#endregion Non-user code (Declarations, constructors, properties)
#region Non-user code
#line hidden
private void InitializeComponent()
{
salesSetup = new NavRecordHandle(this, 311);
inFile1 = new NavRecordHandle(this, 2000000022);
}
protected override Object OnInvoke(Int32 memberId,Object[] args)
{
using (NavMethodScope __local = new NavMethodScope(this, @OnInvoke))
{
switch(memberId)
{
case 1000000000:
{
{
if(args.Length!=0)
{
NavRuntimeHelpers.CompilationError(new NavNCLInvalidNumberOfArgumentsException(@ImportFile, 0, args.Length));
}
ImportFile();
}
}
break;
default:
{
NavRuntimeHelpers.CompilationError(Lang.WrongReference, memberId, 50000);
}
break;
}
return (null);
}
}
protected override void OnClear()
{
this.salesSetup.Clear();
this.inFile1.Clear();
ALSystemVariable.Clear(this.inFile);
}
#line default
#endregion Non-user code
public void ImportFile()
{
using (NavMethodScope __local = new NavMethodScope(this, @ImportFile))
{
NavText tmpstr = NavText.Default(150);
NavText filename = NavText.Default(150);
NavText filename2 = NavText.Default(150);
NavAutomation script = new NavAutomation(__local, NavAutomation.ComponentType.Automation, @{0E59F1D5-1FBE-11D0-8FF2-00A0D10038BC}, @"", null);
NavText txtcode = NavText.Default(1024);
NavVariant retVal = NavVariant.Default(__local);
Int32 count = 0;
Int32 i = 0;
NavText txtCR = NavText.Default(30);
NavText foldername = NavText.Default(1024);
NavAutomation wHSFileSystemObject = new NavAutomation(__local, NavAutomation.ComponentType.Automation, @{0D43FE01-F093-11CF-8940-00A0C9054228}, null, null);
NavAutomation wHSFolder = new NavAutomation(__local, NavAutomation.ComponentType.Automation, @{C7C3F5B3-88A3-11D0-ABCB-00A0C90FFFC0}, null, null);
NavAutomation wHSFiles = new NavAutomation(__local, NavAutomation.ComponentType.Automation, @{C7C3F5B6-88A3-11D0-ABCB-00A0C90FFFC0}, null, null);
NavAutomation wHSFilesCollection = new NavAutomation(__local, NavAutomation.ComponentType.Automation, @{387DAFF4-DA03-44D2-B0D1-80C927C905AC}, null, null);
NavAutomation wHSFile = new NavAutomation(__local, NavAutomation.ComponentType.Automation, @{C7C3F5B5-88A3-11D0-ABCB-00A0C90FFFC0}, null, null);
Int32 fileCount = 0;
Int32 fileInt = 0;
NavAutomation filesCol = new NavAutomation(__local, NavAutomation.ComponentType.Automation, @{EE09B103-97E0-11CF-978F-00A02463E06F}, null, null);
NavText selectedFolder = NavText.Default(1024);
NavText serverFilePath = NavText.Default(1024);
NavText clientTempFile = NavText.Default(1024);
Boolean status = new Boolean();
// IF ISCLEAR(WHSFileSystemObject) THEN
if(wHSFileSystemObject.IsClear)
{
// CREATE(WHSFileSystemObject,TRUE,TRUE);
wHSFileSystemObject.Create(DataError.ThrowError, true, true);
}
// IF NOT WHSFileSystemObject.FolderExists('P:\') THEN BEGIN
if(!(wHSFileSystemObject.InvokeMethod<Boolean>(@FolderExists, @P:\)))
{
ALSystemVariable.Clear(wHSFileSystemObject);
// EXIT;
return ;
}
// WHSFolder := WHSFileSystemObject.GetFolder('P:\');
wHSFolder.ALAssign(wHSFileSystemObject.InvokeMethod<NavAutomation>(@GetFolder, @P:\));
// WHSFiles := WHSFolder.Files;
wHSFiles.ALAssign(wHSFolder.InvokePropertyGet<NavAutomation>(@Files));
// IF ISCLEAR(FilesCol) THEN
if(filesCol.IsClear)
{
// CREATE(FilesCol,TRUE,TRUE);
filesCol.Create(DataError.ThrowError, true, true);
}
// IF ISCLEAR(Script) THEN
if(script.IsClear)
{
// CREATE(Script,TRUE,TRUE);
script.Create(DataError.ThrowError, true, true);
}
// Script.Language := 'VBScript';
script.InvokePropertySet<String>(@Language, @VBScript);
// Script.AddObject('FilesByName', WHSFiles);
script.InvokeMethod<Object>(@AddObject, @FilesByName, wHSFiles);
// Script.AddObject('FilesById', FilesCol);
script.InvokeMethod<Object>(@AddObject, @FilesById, filesCol);
// txtCR := '';
txtCR = new NavText(30, @"");
txtCR = new NavText(30, ALSystemString.SetChar(txtCR, 0, ALCompiler.ToByte(13)));
// txtcode :=
txtcode = new NavText(1024, @dim f1+txtCR+@For Each f1 in FilesByName+txtCR+@ FilesById.Add (FilesById.Count+1), f1+txtCR+@Next+txtCR);
// Script.ExecuteStatement(txtcode);
script.InvokeMethod<Object>(@ExecuteStatement, txtcode);
// // ========================================================================
ALSystemVariable.Clear(script);
// FileCount := FilesCol.Count();
fileCount = filesCol.InvokePropertyGet<Int32>(@Count);
// MESSAGE(FORMAT(FileCount));
NavDialog.ALMessage(new Guid(50000, 15259, 51712, 3, 5, 0, 0, 131, 107, 210, 210), NavFormatEvaluateHelper.Format(ALCompiler.ToNavValue(fileCount)));
fileInt = 1;
Int32 @tmp0 = fileCount;
// FOR FileInt := 1 TO FileCount DO BEGIN
for(;fileInt<=@tmp0
{
// WHSFile := FilesCol.Item(i);
wHSFile.ALAssign(filesCol.InvokePropertySet<Object>(@Item, ( (Object)(i) )));
// filename := WHSFolder.Path + '\' + WHSFile.Name;
filename = new NavText(150, wHSFolder.InvokePropertyGet<String>(@Path)+@\+wHSFile.InvokePropertyGet<String>(@Name));
if(fileInt>=@tmp0)
{
break;
}
fileInt = fileInt+1;
}
// CLEAR(WHSFileSystemObject);
ALSystemVariable.Clear(filesCol);
//
ALSystemVariable.Clear(wHSFileSystemObject);
}
}
}
}
filename = new NavText(150, wHSFolder.InvokePropertyGet<String>(@Path)+@\+wHSFile.InvokePropertyGet<String>(@Name));
I am not a c# expert, but what happens if you just hardcode path in c/al, something like
Looks that c/al -> c# translator can't convert your expression into valid c# code.
but it fails even if i comment away that line, it is the line before that that is the problem.
And i can't hardcode it to something - the whole idea is to get those filenames :-)
I have now tried the same code in 2009 R2 and i get the same errortext
I would like to know why you even need the whole VBScript part? Why not looping over the WSHFiles Collection?
yes, I tried to do that
WHSFile := WHSFiles.Item(i);
But then it complains over my parameters.
the WHSFiles are sorted by names - and I don't know the filenames
all files are there
FileCount := WHSFiles.Count(); works fine
I just don't can't get the names from them :roll:
If you can, i would recommend using .Net interop instead. There you don't have such limitations. The collections work as expected in the System.IO Namespace you will find all you need (Directory Class which returns file names as string)
Or if you must stick to automations, try the "Microsoft Shell Controls And Automation'.Shell" instead.
In the thread it says that .NET only works with R2, I am using 2009 sp1.
But I will try "Microsoft Shell Controls And Automation'.Shell"
No specific order. I just want the name of all the files in a specific folder.
The MSFolder version works!
Thank You all for your suggestions and links
Here is my final code (anyway "final" before put into real context)
thx