| David Park's profileDavid's spaceBlogLists | Help |
David's space |
||||||||||||||||||||||||||||||||||||||||||||||||||
|
April 09 How to: Set Up Visual Studio for Enterprise Portal DevelopmentTo set up Visual Studio for Enterprise Portal development
April 08 Creating a run-time lookup formA standard lookup form is created through relations on the database table, and on the Extended Data Type. To learn about the standard lookup form, click If, however, you need to create a runtime lookup form that looks up other database fields than the ones offered by the standard lookup form, use the application class SysTableLookup and override the lookup method on the relevant form control. How to use the SysTableLookup class
SysTableLookup sysTableLookup = SysTableLookup::newParameters(tableNum(custTable), this);
sysTableLookup.addLookupField(fieldNum(custTable, accountNum));
queryBuildDataSource = query.addDataSource(tableNum(custTable)); queryBuildRange = queryBuildDataSource.addRange(fieldNum(custTable, accountNum)); queryBuildRange.value('A..B'); sysTableLookup.parmQuery(query);
sysTableLookup.performFormLookup(); // super() }
A complete example of overriding the lookup method on a form control
void lookup() { Query query = new Query(); QueryBuildDataSource queryBuildDataSource; QueryBuildRange queryBuildRange;
// Create an instance of SysTableLookup where 'this' the current Form control.
SysTableLookup sysTableLookup = SysTableLookup::newParameters(tableNum(custTable), this); ;
// The field to be shown in the lookup form.
sysTableLookup.addLookupField(fieldNum(custTable, accountNum)); sysTableLookup.addLookupField(fieldNum(custTable, name));
// Limit and arrange data selection.
queryBuildDataSource = query.addDataSource(tableNum(custTable)); queryBuildRange = queryBuildDataSource.addRange(fieldNum(custTable, accountNum)); queryBuildRange.value('A..B'); sysTableLookup.parmQuery(query);
// Perform lookup
sysTableLookup.performFormLookup();
// do not call super().
// super() }
void lookup() { Query query = new Query(); QueryBuildDataSource queryBuildDataSource; QueryBuildRange queryBuildRange; SysTableLookup sysTableLookup; TableId tableId; FieldId fieldId; ; tableId = tablename2id('myTable'); sysTableLookup.parmTableId(tableId); fieldId = fieldname2id(tableId, 'MyField_1'); sysTableLookup.addLookupfield(fieldId); fieldId = fieldname2id(tableId, 'MyField_2'); sysTableLookup.addLookupfield(fieldId);
queryBuildDataSource = query.addDataSource(tableId); queryBuildDataSource.orderMode(OrderMode::GROUPBY); queryBuildDataSource.addSortField(fieldId));
sysTableLookup.parmQuery(query);
this.performFormLookup(sysTableLookup.formRun()); } This manner of creating a lookup form is used in the DocuType form in the application. The full path to the modified lookup method is: \Forms\DocuType\Designs\Design\[Tab:Tab]\[TabPage:Overview]\[Grid:Grid]\StringEdit:ActionClassName\Methods. NoteThe SysTableLookup is limited to making lookups on fields in a table. February 27 Functions of ContainerFROM AX DOCUMENTConInsSyntaxcontainer ConIns (container container, int start, anytype element,... ) Exception messageInserts elements in the container specified by container. The elements are inserted at the position specified by start. If several elements are specified, they must be separated by commas. To insert an element as the first in a container, specify start as 1. To insert after the nth element specify start as n+1. Examplestatic void Job_Examples_conins_conlen_conpeek(Args _args)
You can also assign elements to a container: You can use the += operator to add values of any type into a container. For example, to create a container containing the first ten square numbers:
See AlsoConFind, ConDel, ConLen, ConNull, ConPeek, ConPoke ConFindSyntaxint ConFind (container container, anytype element,... ) Exception messageLocates the first occurrence of a specific sequence of elements in the container specified by container. If several elements are specified in the sequence, they must be separated by commas and given in the correct sequence. The elements can be of any data type. Return ValueThe function returns 0 (the item was not found) or the item’s sequence number. Examplestatic void Job_Examples_confind(Args _args)
See AlsoConDel , ConIns , ConLen , ConNull , ConPeek , ConPoke
ConLenSyntax
Exception messageReturns the number of elements in the container specified by container. Examplestatic void Job_Examples_conins_conlen_conpeek(Args _args) See AlsoConFind, ConDel, ConIns, ConNull, ConPeek, ConPoke
ConNullSyntax
Exception messageReturns a null container. Use the function to explicitly dispose of the contents of a container. Examplestatic void Job_Examples_connull(Args _args)
See AlsoConFind, ConDel, ConIns, ConLen, ConPeek, ConPoke
ConPeekSyntax
Exception messageReturns a specific element from the container specified by container. The element is specified by number. Specify 1 to get the first element. The conpeek function automatically converts the peeked item into the expected return type. Strings can automatically be converted into integers and reals, and vice versa. Examplestatic void Job_Examples_conins_conlen_conpeek(Args _args)
You can extract more than one element from a container with a composite assignment:
See AlsoConFind, ConDel, ConIns, ConLen, ConNull, ConPoke
ConPokeSyntaxcontainer ConPoke (container container, int start, anytype element,... ) Exception messageModifies the container specified by container by replacing one or more of the existing elements with the specified elements. The position of the first element to be replaced is specified by start. If several elements are specified, they must be separated by commas. To replace the first element, specify start as 1. Examplestatic void Job_Examples_conpoke(Args _args) ConFind , ConDel , ConIns , ConLen , ConNull , ConPeek
March 26 Starting the code profiler from codeoriginal link: http://axstart.spaces.live.com/The code profiler is a tool that tells you how many milliseconds a line of x++ code need to be executed. This tool is most of time used for analyses of defined scenario of your process. This code profiler runs the code in debug mode. So a process of 10 minutes can take 30 minutes when the code profiler is active. So a large run of 1 hour, reproduce with the code profiler, makes no since. The trick is to profile small part of the process. We can do this with existing macros in AX.
Later on you have to calculate the sum and line totals for that run. Give this run a new name, otherwise you don’t get the line, method and class totals. I think this is a bug. March 14 Send Mail through codeAX uses CDO.Message component to send a email and Here's a example.
static void SendMailQuick(Args _args)
{ SysMailer mailer; ; mailer = new SysMailer(); mailer.quickSend("david@dickiesmedical.com", "david@dickiesmedical.com", "test subject", "test body", "sjin@dickiesmedical.com", "c:\\testfile.txt"); } or other way
before using this way you need to setup email parameters through Administration - Setup - E-mail parameters
static void sendMail(Args _args)
{ #SysMailer #DEFINE.SenderName('David Park') #DEFINE.Sender('david@dickiesmedical') #DEFINE.Recipient('david@dickiesmedical.com') #DEFINE.Recipient2('sjin@dickiesmedical.com') #DEFINE.Subject('test mail subject') #DEFINE.MessageBody('test mail message body') SysMailer mailer; SysMailerAddressField tos; FileIOPermission fileIOPermission; InteropPermission interopPermission; str relayServer; int portNumber; str userName; str password; boolean NTLM; str filePathName; str tempPath; SysEmailParameters parameters = SysEmailParameters::find(); ; if (parameters.SMTPRelayServerName) relayServer = parameters.SMTPRelayServerName; else relayServer = parameters.SMTPServerIPAddress; portNumber = parameters.SMTPPortNumber; userName = parameters.SMTPUserName; password = SysEmailParameters::password(); NTLM = parameters.NTLM; //fileIOPermission = new FileIOPermission('','r'); //fileIOPermission.assert(); //tempPath = WinAPIServer::getTempPath(); //CodeAccessPermission::revertAssert(); interopPermission = new InteropPermission(InteropKind::ComInterop); interopPermission.assert(); mailer = new SysMailer(); CodeAccessPermission::revertAssert(); mailer.SMTPRelayServer(relayServer, portNumber, userName, password, NTLM); mailer.fromAddress(#Sender,#SenderName); tos = mailer.tos(); //tos.appendAddress("david@dickiesmedical.com,sjin@dickiesmedical.com"); tos.appendAddress(#Recipient); mailer.priority(1); mailer.subject(#Subject); mailer.htmlBody(#MessageBody); mailer.sendMail(); } Or
If you are up and running E-mail distributor batch, then simple insert apropriate data into SysOutgoingEmailTable and SysOutgoingEmailData(Optional). batch will get the record from the table and try to send out.
March 12 Create Progress IndicatorsUse a progress indicator during operations that take more than 2 seconds.
Display an Hourglass Pointer
Both of these methods are on the The hourglass pointer is displayed until you call the
Example: Display an Hourglass PointerThe following example overrides the
Display a Progress Bar
During the execution, the progress indicator is updated accordingly. The estimated time remaining is calculated and displayed. The default update interval is 3 seconds. If the task of updating the display takes more than 10% of the update interval due to latency on the network connection, the update interval is increased by 1 second.
Example: Use a Single Progress IndicatorThe following example creates a simple progress indicator.
Use More Than One Progress IndicatorIf you have a more complex operation, you can have more than one progress indicator. All of the previously described methods have a default parameter that indicates which progress indicator (or bar) is being referred to.
Example: Use Three Progress Indicators
User Input During an OperationFollowing are progress indicator options for user input during an operation:
Using Progress Indicators with the Runbase Framework
Use the
Indicating progress during the actual operation is similar to the standard Operation Progress framework. Use the member variable
If you have more than one progress bar, use the
February 27 selection of several records in a grid (Multi select)To unnecessary code to avoid duplications, we can even with a for-loop work: void clicked() Void clicked () { ( CustTable custTable; CustTable custTable; ; for (custTable = CustTable_ds.getFirst(true) ? For (custTable = CustTable_ds.getFirst (true)? CustTable_ds.getFirst(true) : CustTable_ds.getFirst (True): CustTable_ds.cursor(); CustTable_ds.cursor (); custTable; CustTable; custTable = CustTable_ds.getNext()) CustTable = CustTable_ds.getNext ()) { ( //do something with custTable / / Do something with custTable info(custTable.accountNum); Info (custTable.accountNum); } ) } ) CustTable_ds.getFirst() gibt nur etwas zurück, wenn mehrere Datensätze markiert sind. CustTable_ds.getFirst () is only slightly back when several records are marked. Man kann sich also die Abfrage nach CustTable_ds.anyMarked() sparen. It is also the query () CustTable_ds.anyMarked save. February 18 how to init the form in the maximized mode?I think it depends on design properties of your form. My form has following properties Width - Column width Height - Column height WindowResize - Dynamic and move code I suggested in run() method -- Ruslan Goncharov http://rusgon.blogspot.com/ "M Elsawah" wrote: > Hi Ruslan > > Thanks alot for your help > but > It works but over the width only, i want the form to look like the action of > clicking on Maximize button, have you got what i mean? > > Thanks. > > "Ruslan Goncharov" wrote: > > > Try to do following lines in the init() method on the form > > public void init() > > { > > #WinApi > > ; > > super(); > > > > WinApi::showWindow(this.hWnd(), #SW_SHOWMAXIMIZED); > > } > > -- > > Ruslan Goncharov > > > > http://rusgon.blogspot.com/ > > > > > > "M Elsawah" wrote: > > > > > Hi all, > > > I just ask about how to make the form open in the maximized mode in both > > > width and height? also i want to ask how to make the controls resized > > > relative to the form size? > > > Please try to reply me ASAP > > > Thanks. January 31 save and open word documentstatic void WordTemplateOpen() { COM wordApp; COM wordDocuments; wordApp = new COM("word.application"); wordDocuments = wordApp.Documents(); wordDocuments.Open("c:\\MyBelovedTemplate.dotx"); wordApp.visible(true); } static void WordSaveAs() { COM wordApp; COM wordDocuments; COM wordDocument; COM wordRng; wordApp = new COM("word.application"); wordApp.visible(false); wordDocuments = wordApp.Documents(); wordDocument = wordDocuments.add(); wordRng = wordDocument.range(0,0); wordRng.insertafter("Hallo Microsoft Word"); wordDocument.SaveAs("C:\\MyBelovedWordDocument.doc"); wordApp.visible(true); } "mason" wrote: November 30 How to send data to Excelstatic void Send_toExcel(Args _args) { SysExcelApplication ExcelApplication; SysExcelWorkBooks ExcelWorkBooks; SysExcelWorkBook ExcelWorkBook; SysExcelWorkSheets ExcelWorkSheets; SysExcelWorkSheet ExcelWorkSheet; SysExcelRange ExcelRange; CustTable ct; int row; ; ExcelApplication = SysExcelApplication::construct(); ExcelApplication.visible(true); ExcelWorkBooks = ExcelApplication.workbooks(); ExcelWorkBook = ExcelWorkBooks.add(); ExcelWorkSheets = ExcelWorkBook.worksheets(); ExcelWorkSheet = ExcelWorkSheets.itemFromNum(1); while select * from ct
{
row++;
ExcelWorkSheet.cells().item(row,1).value(ct.AccountNum);
ExcelWorkSheet.cells().item(row,2).value(ct.Name);
}
} --Gundhawk 02:30, 15 September 2007 (EDT)
================================================================= static void CreateExcelDokument(Args _args) November 14 reset temporary tableFrom Kashperuk Ivan
=================
You can use 3 ways: 1 is slow, 2 are fast. Slow way: delete_from tmpTable; Fast way 1: tmpTable = null; // Use this only if you are experienced in using tmpTables and handling objects Fast way 2: void method() { TmpTable tmpTable; void clearTmpTable() { TmpTable tmpTableLocalEmpty; ; tmpTable.setTmpData(tmpTableLocalEmpty); } tmpTable.SetTmpData(Class::getData()); //here tmpTable has data clearTmpTable() //here tmpTable doesn't have data } Which way to use is for you to decide -- Kashperuk Ivan (Vanya), Dynamics AX MCBMSS My blog - http://kashperuk.blogspot.com MorphX IT in Russian - http://www.lulu.com/content/723888 "HY Choo" wrote: > Hi all, > > how to reset the temp table to initial state after settmpdata? > > TIA > > Choo September 12 CAS (Code Access Security)=======================================================\
Code Access Security
Code Access Security (CAS) helps protect APIs that have potential security risks when the APIs are running on the server. CAS-enabled APIs called on the server require the use of a permission class—one of the classes derived from
This error is also generated if permission is asserted, but the code is running on the client. Permission is required only for CAS-enabled APIs that run on the server. The string supplied in the error message is the name of one of the following permission classes:
For a list of CAS-enabled APIs, see Secured APIs. You can CAS-enable your own APIs. For more information, see Secure an API that Executes on the Server Tier. Call a CAS-enabled APIAugust 03 unlocking objectwhen you got "error: Unable to save. xxx is locked by xxx", you need to check Tools -> Development Tools -> Application objects -> Locked application objects.
you may delete any of record in it. July 30 How to setup Axapta batch server running as user defined windows servicecheck this out.
another article
translated
July 26 Configuration in Title barThanks
============================================
Configuration in title bar
One common complain with Dynamics Ax 4.0 is that it is not possible for the user to determine in which environment they are working. Particularly for consultants/developers who often have multiple Ax applications open at one time, this is very frustrating and can easily lead to errors (developing in the wrong application). In Axapta 3.0 information was displayed in the title bar allowing users to determine the application, but this is missing in Ax 4.0 This simple fix will display the configuration name in the main Dynamics Ax window title bar. You need to simply override the workspaceWindowCreated() method in the info() class (special class nearly at the bottom of the Classes node in the AOT) and add a single line of code. After the change, the method should appear as follows:
void workspaceWindowCreated(int _hWnd) { ; // Put workspace window specific initialization here. // Show config in title bar WinAPI::setWindowText(_hWnd, strFmt("%1 - %2", WinAPI::getWindowText(_hWnd), xInfo::configuration())); } Another option is shown below. This will put the current AOS and server name, as well as the logged in development layer, after the standard title bar text.
void workspaceWindowCreated(int _hWnd) { SqlSystem sqlSystem = new SqlSystem(); LoginProperty loginProperty = sqlSystem.createLoginProperty(); ; // Put workspace window specific initialization here. // Show application details in title bar if (loginProperty) { WinAPI::setWindowText(_hWnd, strFmt("%1 - %2@%3 (%4)", WinAPI::getWindowText(_hWnd), loginProperty.getDatabase(), loginProperty.getServer(), this.currentAOLayer())); } } The details for these fixes came originally from posts to the microsoft public axapta newsgroup. [edit] Ax 3.0 solutionfrom AxForum \Classes\Info\onEventGoingIdle //Event fired by kernel when the client goes idle. //It is not fired during CTRL-Break dialog. void onEventGoingIdle() { this.operationProgressClear(); this.endLengthyOperation(true); // there should be a user who will work if error occured if(strLwr(curUserID())!='admin') TitleChanger::changeTitle(); } TitleChanger::changeTitle: static void changeTitle() { #define.WM_SETTEXT(0x000C) str caption; str prefix=new Session().AOSName()+": "; int defWindowProc( int _handle, int _msg, int _wParam, str _lParam ) { int ret; DLL _DLL = new DLL('USER32'); DLLFunction _defwproc = new DLLFunction(_DLL, 'DefWindowProcA'); ; _defwproc.returns(ExtTypes:: DWord); // LRESULT _defwproc.arg(ExtTypes:: DWord); // handle window _defwproc.arg(ExtTypes:: DWord); // message _defwproc.arg(ExtTypes:: DWord); // wparm _defwproc.arg(ExtTypes::String); // lparm return _defwproc.call(_handle, _msg, _wParam, _lParam); } ; caption = winapi::getWindowText(infolog.hWnd()); if(!StrUtils::startsWith(caption, prefix)) defWindowProc(infolog.hWnd(), #WM_SETTEXT, 0, prefix + caption); } StrUtils::startsWith: // string _s begins with _suffix static boolean startsWith(str _s, str _prefix) { return strLen(_s)>=strLen(_prefix) && subStr(_s, 1, strLen(_prefix))==_prefix; } July 06 [QNA] Createing a user in AD from AXThanks for the tip, but I figured out it was just as easy to create a code library (DLL) in C# and use it in Ax. It works fine for me at least. Here is the C# code I used: ------------------------------------ using System; using System.Collections.Generic; using System.Text; using System.DirectoryServices; namespace Microsoft.Dynamics.CreateADUser { public class NewUser { string defaultNC; string alias; string fullName; string password; string ou; public void setDomain(string _defaultNC) { defaultNC = "DC=" + _defaultNC; } public void setAlias(string _alias) { alias = _alias; } public void setFullName(string _fullName) { fullName = _fullName; } public void setPassword(string _password) { password = _password; } public void setOu(string _ou) { ou = _ou; } public string execute() { DirectoryEntry container, user; string ret; try { //This creates the new user in the "users" container. //Set the sAMAccountName and the password container = new DirectoryEntry("LDAP://OU=" + ou + ", " + defaultNC + ",DC=NO"); user = container.Children.Add("cn=" + fullName, "user"); user.Properties["sAMAccountName"].Add(alias); user.CommitChanges(); user.Invoke("SetPassword", new object[] { password }); //This enables the new user. user.Properties["userAccountControl"].Value = 0x200; //ADS_UF_NORMAL_ACCOUNT user.CommitChanges(); ret = "OK"; } catch (Exception e) { ret = e.ToString(); } return ret; } } } ------------------------------------ Just compile and put the dll-file in the client\bin folder of Ax and create a reference from the aot and use the class like this in Ax: ------------------------------------ static void Job1(Args _args) { Microsoft.Dynamics.CreateADUser.NewUser user; ; user = new Microsoft.Dynamics.CreateADUser.NewUser(); user.setDomain(/*yourdomain*/); user.setAlias(/*alias of the user you want to create*/); user.setFullName(/*Full name of the user*/); user.setPassword(/*Password*/); user.execute(); } ------------------------------------ Regards, Erlend "Max Belugin [MVP]" wrote: > I think, you can find and example in C# and port it to X++ > > http://www.google.com/search?q=create+user+active+directory+C%23 > > -- > my blog: http://axcoder.blogspot.com > freeware sidebar for ax: http://belugin.info/sidax > > > "Erlend Dalen" wrote: > > > Is it possible to create a new user in AD from Ax 4.0? > > I have been looking into the System.DirectoryServices, but I haven't been > > able to figure out to make it work yet....can anyone help? > > > > Regards, > > Erlend June 28 How to setup AX batch server running as user defined windows serviceHow to setup Axapta batch server running as user defined windows service
Integrated with Visual source safe(VSS)Notes about my experience in setup of Microsoft Dynamics AX 4.0 integrated with Microsoft Visual Source Safe.
June 27 Accessing the active query formsSetting the Modify the system-generated query to display a different set of data as the result of user input in the form.
Declare a Variable of the Type QueryBuildRangeDeclare a variable of the type
Initialize the QueryBuildRange VariableInitialize the The initialization must be after the
Placing the initialization after the The code sets the Following is an explanation of the code:
Modify the executeQuery MethodThe In the following example, the
Use Expressions in Query Rangecopy from developer help
==================
Query range value expressions can be used in any query where you need to express a range that is more complex than is possible with the usual dot-dot notation (such as 5012 .. 5500). For example, to create a query that selects the records from MyTable where field A equals x or field B equals y, do the following.
The rules for creating query range value expressions are:
Values must be constants in the expression, so any function or outside variable must be calculated before the expression are evaluated by the query. This is typically done by using strFmt. The example above will then look like the following code example.
To get complete compile-time stability you should use intrinsic functions to get the correct field names, as shown in the following code example.
Example using "inter table" relations
passing dynalink from form to form// regenerate the record from cartonInquiry to onhand form
void clicked()
{
WMSPallet wMSPallet;
Args args = new Args(); ; args.caller(this); wMSPallet = WMSPallet::find(sunWMSCartonInquiryView.wMSPalletId); args.record(wMSPallet); new MenuFunction(menuitemdisplaystr(InventOnhandItem), MenuItemType::Display).run(args); } June 26 report design sectionSection:
Prolog
PageHeader : print on all pages in case multi-paged report Header : print only one page on first Section Group
Footer : print only last page right after body section. you may control position of page with TOP, BOTTOM properties.
PageFooter : print on all pages on the bottom Epilog : add new page next to the last page and print on top of it.
ProgrammableSection June 24 AX4.01 print PDF using EPHi,
I dont feel that there is any problem with the image path or location, since company logo is stored and passed as container. As per my research there is some problem in executing image class (run on client ) initilization which may require some thing from client side. As EP runs on server its not able to initilize it. Even i tried the diffrent way of passing refrence to bitmap field (Resources, file path, hardcoded server file path) but nothing seems working. Infact Image class is not able to load the the bitmap data provided by any mean. Any thought on same will be appreciated. Thanks, JJ "Chris (Toronto)" wrote: > Hey JJ, > > The "Publish Images" routine just moves the images onto the web server... > The problem still remains if the files are located on the web server, or on a > share on another server... Same GDI Error. > > I am still struggling with this, no solution found yet. > > Chris > > P.S. It was interesting to see my slightly modified post today! > > > "Alpesh" wrote: > > > ...sorry correct AX path should be: > > Administration>>Setup>>Internet>>Enterprise portal>>Publish > > Images. > > > > "Alpesh" wrote: > > > > > Hello, > > > > > > I have not been able to get to the bottom of this yet. However, I have > > > determined that if you navigate to Administration>>Setup>>Internet>>Publish > > > Images. And run the process, all the images against the following tables: > > > "CompanyImage" > > > "EmplTable" > > > "ECPPresentation" > > > "EPParameters" > > > > > > will be copied to: > > > "..\Program Files\Common Files\ Microsoft Shared\ web server > > > extensions\60\TEMPLATE\LAYOUTS\ep\images" > > > > > > The challenge I have now is how to get my, say for example, AX report, to > > > resolve this when in EP. > > > > > > Please note that I am not sure if this line of investigation is correct, but > > > it seems logical at the moment! > > > > > > Can anybody out there help? > > > > > > I will update you if I get further. > > > > > > Alpesh > > > > > > "jj" wrote: > > > > > > > I am also facing the same issue ... is there any solution or alternative you guys find out ? > > > > > > > > EggHeadCafe.com - .NET Developer Portal of Choice > > > > http://www.eggheadcafe.com > > > > Hello Chris, We have got the same issue. I am testing one or two thoughts on resolving this. Will let you know when I am done. Alpesh "Chris (Toronto)" wrote: > Alpesh, > > Thanks for your guidance on the Event log... Your right. > > The error I'm getting is coming from the PDF Writer class, and it's because > of an image.... I've read a few posts that talk about removing images from > reports before printing... But this is not solution... we need the images. > > Any ideas on how to fis this error? (Application Error Log listed below) > > Chris > > > The Microsoft Dynamics session get object call runWebletItem failed. > > GDI+ generic error. > (C)\Classes\Image\new > (C)\Classes\PDFViewer\writeBitmap - line 76 > (C)\Classes\ReportOutputUser\writeField > (C)\Classes\ReportOutputUser\printViaClass > (C)\Classes\ReportOutput\printPDF > (C)\Classes\ReportOutput\printToTarget > (S)\Classes\ReportRun\print > (S)\Classes\ReportRun\run > (S)\Classes\ioSendDocument\printSpecSheetPDF - line 43 > (C)\Web\Web Forms\cmooTest\Methods\init > (C)\Classes\WebFormHtml\run - line 5 > (C)\Classes\WebFormHandler\new - line 45 > (C)\Classes\WebPortalExecutionEngine\processWebContentItem - line 70 > (C)\Classes\WebFormWeblet\run - line 8 > (C)\Classes\WebLet\runFrame - line 39 > (C)\Classes\WebAppWebLet\runFrame - line 4 > (C)\Classes\WebPortalExecutionEngine\runWebletItem - line 64 > > Object 'Image' could not be created > File Exists: true, \\itvaos2003\EpFiles\Spec(149545).pdf > > Microsoft.Dynamics.BusinessConnectorNet.XppException > at Microsoft.Dynamics.BusinessConnectorNet.AxaptaObject.Call(String > methodName, Object[] paramList) > > > "Alpesh" wrote: > > > Do you have a bitmap on your source file? If so, remove it and then try > > generating your report again. Also, maybe you already know this, if there is > > an error generated by EP it will be written to the Application Event lof on > > the IIS Server. > > > > Alpesh > > > > "Chris (Toronto)" wrote: > > > > > Hello, > > > > > > I am attempting to create a PDF from a report on the fly on the Enterprise > > > portal. > > > > > > The following code is being used to generate the report: > > > > > > args = new args(); > > > args.name(reportStr(ioItemSpec)); > > > args.record(ioTItleLine); > > > if (_showExtended) > > > { > > > args.parmEnum(1); > > > } > > > args.parm(num2str(_itemPrice,0,2,0,0)); > > > > > > reportRun = new reportRun(args); > > > reportRun.args().name('KeepSettings'); > > > reportRun.query().interactive(False); > > > reportRun.report().interactive(False); > > > reportRun.setTarget(printMedium::File); > > > reportRun.printJobSettings().setTarget(PrintMedium::File); > > > reportRun.printJobSettings().format(PrintFormat::PDF); > > > reportRun.printJobSettings().warnIfFileExists(False); > > > reportRun.printJobSettings().suppressScalingMessage(True); > > > reportRun.printJobSettings().packPrintJobSettings(); > > > reportRun.printJobSettings().fileName(filename); > > > > > > reportRun.run(); > > > > > > This works great when the report is printed from a client machine.... But > > > when the report is generated by a webform, or a class called from the EP, the > > > PDF is corrupt (only 1 K) > > > > > > The PDF file created when opened in notepad is: > > > > > > %PDF-1.3 > > > % Quotation - Report > > > % Generated by Guest on 3/21/2007 at 14:26:54 > > > 5 0 obj << > > > /Creator (Axapta) > > > /Producer (Guest) > > > /Title (Quotation - Report) > > > /Author (Axapta \(build2163\)) > > > /Subject (Quotation - Report) > > > > > > > > > Any ideas on why the PDF report is not being generated correctly when the > > > report is called from the Enterprise Portal? > > > > > > Any help would be greatly appreciated! > > > > > > Chris print filtered list onlyThanks Mathias i'll prove and let you now you -- Juan Manuel "Mathias" wrote: > Am Tue, 17 Apr 2007 15:16:00 -0700 schrieb Juan Manuel: > > > Hi, All I'm Newbie in Axapta and working in a developement where i fill a > > form with a temporary table and the user look for information and make some > > filters, when the user find the raight information he want to print the > > information in a report. > > > > I'm al ready make an inform but when is calling bring the last filter used, > > is there some way to know the filters used by the user and passing this > > values to the class that make the inform ???? > > > > Any one has/know some exemple of doing this??? > > > > regadrs and thanks in advance > > Hi, > > you can use element.dataSource() to get the query with all ranges on your > form. > Here is an example that will show you all the ranges in a new dialog. Just > use a button on your form and overload the method "clicked". > > void clicked() > { > FormRun fr; > FormDataSource fds = element.dataSource(); > queryRun queryRUn; > ; > super(); > queryRUn = fds.queryRun(); > queryRun.prompt(); > > } > > > And you can use this query in your report to get all records based on it. > To call your report you can use the following code to parse the query from > your from to your report. > > void clicked() > { > ReportRun reportRun; > FormDataSource fds = element.dataSource(); > queryRun queryRUn; > args args = new Args(); > ; > query = fds.query(); > args.name(reportstr(yourReportName)); > args.parmObject(fds.queryRun()); > super(); > > reportRun = new ReportRun(args); > reportRun.init(); > reportRun.run(); > reportRun.wait(); > } > > after that you have to set up queryrun on your report. > > i hope this will help. > -- > Mathias Füßler > My blog: http://starside.eu > |
|
|||||||||||||||||||||||||||||||||||||||||||||||||
|
|