Microsoft Dynamics GP Developing for Dynamics GP
A blog dedicated to the Microsoft Dynamics GP Developer & Consultant community
 
Welcome to MSDN Blogs Sign in | Join | Help

Developing for Dynamics GP

by David Musgrave (Australia) and the Microsoft Dynamics GP Developer Support Team (USA)

News

  • Please use the Blog Feedback? - Contact Us link at the top of the page to email questions relating to the blog itself.

    If you wish to ask a technical question, please use the links below to ask on the Newsgroups. If you ask on the Newsgroups, others in the community can respond and the answers are available for everyone in the future.

    Please do not use comments on pages and posts to ask questions unrelated to the topic on that page or post.



    Dates of Interest:

    11-Jul-2008: Blog Created by David Musgrave.
    03-Oct-2008: Syndicated to the Dynamics Communities.
    10-Oct-2008: First Post by Scott Stephenson.
    04-Nov-2008: First Post by Dave Dusek.
    11-Nov-2008: First Post by Beth Gardner.
    28-Nov-2008: First Post by Chris Roehrich.
    30-Dec-2008: First Post by Patrick Roth.
    24-Feb-2009: First Post by Greg Willson.
    22-Apr-2009: First Post by David Clauson.
    04-May-2009: First Post by Ryan Wigestrand.
    19-Jun-2009: First Post by Dawn Langlie.
    03-Jul-2009: First Post by Emily Halvorson.
    23-Sep-2009: Created Twitter account with blog feed.
    20-Nov-2009: First Post by Alice Newsam.



    WorldMaps Statistics since
    24-Feb-2009:




    Click for WorldMaps Stumbler



    Translator Tool:




    Social Networking & Syndication

    Follow David Musgrave and the blog on:

    David Musgrave on Twitter

    David Musgrave on LinkedIn

    This blog at Dynamics Communities


    Disclaimer

    This blog is provided "AS IS" with no warranties, and confers no rights.

    The links in this blog may lead to third-party Web sites. Microsoft provides third-party resources to help you find customer service and/or technical support resources. Information at these sites may change without notice. Microsoft is not responsible for the content at any third-party Web sites and does not guarantee the accuracy of third-party information.

Contents

Favourite Posts

Blog Links

Newsgroups Links

Resources Links

Microsoft Dynamics GP Source Code Program for Asia Pacific

David Meego - Click for blog homepageI have some fantastic news for developing partners in the Asia Pacific region. The Microsoft Dynamics GP Source Code Program is finally available for Asia Pacific.

Before Microsoft acquired Great Plains, there was a source code program available for partners worldwide.  When Microsoft completed its acquisition of Great Plains the program was suspended.  Existing Source Code partners would continue to have access to source code, but no new partners could sign up.

Eventually, the program was restarted. Initially only available to North American partners, but later it was also opened to Partners in the LATAM (Latin American) and EMEA (Europe, Middle East & Africa) regions.  Partners in the Asia Pacific region had not been able to get access.... until now.

If you wonder what the benefits of having access to the Source Code is, please have a read of my previous post on the topic:

Do I need access to Microsoft Dynamics GP Source Code?


Here is the PartnerSource link for the documentation for the program:

Source Code Program for Microsoft Dynamics GP - Asia Pacific
https://mbs.microsoft.com/partnersource/worldwide/asiapacific/partneressentials/mspp/SourceCodeProgramGP_APAC Secure Link

If you have any questions, email gpsource@microsoft.com.

I am really excited as this is something I have been pushing for for a number of years and it is finally here.

David

See you at Microsoft Dynamics Convergence 2010

David Meego - Click for blog homepageMicrosoft Dynamics Convergence 2010

Fantastic News. I am going to my first Convergence conference and, even better, I will be presenting 2 concurrent sessions with my partner in crime, Mariano Gomez

Back in November, Mariano and I presented together at the Microsoft Dynamics GP Technical Conference 2009 and it was a huge success.

So now, we get a chance to do it again at the Microsoft Dynamics Convergence 2010. Details on our sessions will be posted later.

Please see the video below for details of some of the great volunteering opportunities that will be happening at Convergence. 

This is going to be a fantastic opportunity to catch up with members of the Dynamics GP community.  Mark Polino will be back presenting his Tips session

Check out Mariano's announcement post on his blog.

Looking forward to seeing you in Atlanta (24th - 27th April 2010).

David

Fixing missing Note Index values

David Meego - Click for blog homepageA recent newsgroup post asked about how to fix the error message shown below from occurring when clicking the Attach button on the Note window for a record level note.

"The note ID has not been set." 

The cause of the message is that the 'Note Index' value for the Transaction or Master record has not been set and so remains at zero. 

The post Understanding Notes and the Note Index field explains how the Note Index is used and where the next Note Index comes from.  It also explains how cross linked notes can occur.  This post will discuss missing Note Index values and how they can occur. 

The usual cause is because the data has been imported in some way and the import process did not populate the 'Note Index' field. Depending on what the import process actually is, you might need to log this issue with support so that it can be fixed. 

Also, If you can make this problem occur for a master record or transaction newly entered via the user interface, then there is a bug in the code for that window and you will need to log this issue with the developer.

So, once there is data with a missing Note Index value, how can we fix it.... The answer is "easily".

My friend, Robert Cavill, provided me with a script he had created which can scan a table for missing 'Note Index' values. The script updates the table with the next Note Index for the company. It does so by using the existing DynamicsGP stored procedure: smGetNextNoteIndex. This AssignNoteIndex.sql script is attached to the bottom of this post. You just need to specify the table name to process by editing the value at the top of the script.

Before using AssignNoteIndex.sql, I would suggest running the script in the Knowledge Base (KB) article Cross-linked or incorrect notes indexes in Microsoft Great Plains (KB 872678) Secure Link. This will ensure that the Note Index values used are higher than any existing values.  The FindMaxNoteIndex.sql script from this KB is also attached to the bottom of this post.

Should you make regular use of the sample company Fabrikam (TWO database), I would also suggest running the FindMaxNoteIndex.sql script on this database as well. This is especially worthwhile if you have third party products that have added sample data.

The AssignNoteIndex.sql script and the FindMaxNoteIndex.sql script are available from the attachment at the bottom of this post.  They can be executed against any company database.

For other posts on the topic of Notes and OLE Attachments see the following posts:

Understanding Notes and the Note Index field 

OLE Attachments and Record Notes

All about the Dexterity OLE Container

Copying Record Notes and OLE Attachments between Companies

I hope you find these scripts useful.

David

The "Right" Way to Maximize the Growing Number of Online Resources for Microsoft Dynamics GP

David Meego - Click for blog homepageMy friend Victoria Yudin (MVP) has written a great article which has been posted on the MSDynamicsWorld.com site.

The article: The "Right" Way to Maximize the Growing Number of Online Resources for Microsoft Dynamics GP, discusses the best methods to get help from the online resources and Microsoft Dynamics GP community.  The main tips she mentions are:

  1. Be specific and thorough in describing your problem.
  2. Try to find the answer yourself first.
  3. Be a smart "buyer".
  4. Be considerate.

However, you will need to read her article to get the details.  It is well worth the time. You can also check out Victoria's post from her blog:

Maximizing Dynamics GP online resources

Note: To read the entire article, you will need to sign up for a free account, if you don't have one already.

I am a firm believer in helping people help themselves.  I am happy to point people in the right direction after they have done their own research on a topic.  This way they learn how to find the answers themselves and get a much better understanding of the problem and the subsequent solution. 

Thank you Victoria. 

David

Limitations of Dexterity Table Triggers

David Meego - Click for blog homepage"Why doesn't my Dexterity table trigger fire when the table is changed."

I have heard this question asked a number of times and so I thought I would highlight some of the possible reasons for the trigger failing to fire.  Some of the reasons can be resolved by coding, while other reasons are a limitation in the way Dexterity table triggers work and cannot be resolved from inside Dexterity.

Dexterity triggers are client side triggers which work from inside the current instance of the Dexterity application. They can only "see" what happens in the that instance of the application.  A Dexterity table trigger does not involve anything at the database level, there will not be a SQL Server trigger registered.

Dexterity table triggers are registered against a particular table and can be set as application wide (by using a 0 for the second parameter below) or restricted to a single form. You can register multiple triggers to have triggers restricted to multiple forms.  They are registered for specific table event(s).

The syntax for the registration of Dexterity table triggers is shown below:

Trigger_RegisterDatabase(anonymous(table table_name), form form_name , table_operations, script processing_procedure {, tag})

where table_operations can be any of the following operations (add the constants together when more than one operation is needed):
 
TRIGGER_ON_DB_READ   (1)
TRIGGER_ON_DB_READ_LOCK   (2)
TRIGGER_ON_DB_ADD   (4)
TRIGGER_ON_DB_UPDATE   (8)
TRIGGER_ON_DB_DELETE   (16)
 
Note: the value of the constant is shown above in parenthesis.

For trigger to fire, the table event must:

  • Be a successful table event (no errors at the database level).
  • Occur using a table buffer which has the trigger registered against it.
  • Be one of the operations defined when the trigger was registered.

For tables not in the Dynamics.dic, you will need to use cross dictionary triggers using the Trigger_RegisterDatabaseByName() function.


So based on the information above, the following situations could cause a table change to occur without the table trigger firing:

  1. The table change is made by an external (non-Dexterity) application. This can be any external program such as eConnect, Integration Manager, Business Portal, directly at the table level by a SQL Administrator or a third party customisation.
     
  2. The table change is made from within the Dexterity application by a non-Dexterity method.  This could be a call to a SQL stored procedure, use of pass through SQL scripts or even access via customisation written using Visual Studio Tools or Visual Basic for Applications (VBA) and ActiveX Data Objects (ADO). Any method which does not use Dexterity commands with a table buffer.
     
  3. The Dexterity customisation with the table trigger is not installed on the application instance running.
     
  4. The table event is using Dexterity commands, but is using a different table buffer to the one against which the trigger is registered.
     
  5. The table event is using Dexterity commands on the same table buffer, for different operations for which the trigger is registered.
     
  6. The table event is using a different table definition to the one against which the trigger is registered. In Dexterity it is possible to have duplicated table definitions referring to the same physical table. This could be to facilitate opening the table twice at the same time or could be because a customisation needs access to a table in a 3rd party product and it was better to duplicate the table rather than use pass through sanScript via the execute() function.

The first two of the reasons are situations where a Dexterity table trigger is not going to work as Dexterity just never "sees" the table change being made. The only method available for these situations is to use a trigger at the SQL Server level.

The third reason is easily solved by installing the customisation chunk file on all workstations.  It was only in this list to highlight the importance of all workstations having all the same dictionaries installed.

The fourth reason is important, but can be coded around.  Using an unrestricted (no form specified) table trigger is not recommended as it could cause the trigger to fire at unexpected times. (For example: when posting, running table maintenance or history removal.) So most developers use one or more table triggers restricted to specific forms.  However, those triggers will only fire if the table event occurs in the specified form's table buffer.  If the code on that form uses a function or procedure to perform the table event and the form's table buffer is not passed as a parameter, a separate instance of the table buffer will be created for the scope of the function or procedure.  As this separate table buffer is not the same as the form's table buffer, a form restricted table trigger will not fire. In this situation it might require an unrestricted table trigger to be used.

Note: If using an unrestricted table trigger, it is good practice to make sure it will not fire at unexpected times.  It is possible to use additional triggers to enable and disable the trigger using the tag value captured when the table trigger was registered.  For example, the trigger could be disabled immediately after registration and then enabled just before the function or procedure described above is executed and then disabled again afterwards.  This is a similar method to the Three Trigger Technique.

The fifth reason is not so common, but can also be changed in the code. It is most likely to happen when using a read trigger.  The get table command does not apply a lock and so is covered by the TRIGGER_ON_DB_READ operation.  The change table and edit table commands do apply locks and so are covered by the TRIGGER_ON_DB_READ_LOCK operation.  If you wish to capture any read event (with or without a lock) you need to use TRIGGER_ON_DB_READ + TRIGGER_ON_DB_READ_LOCK.  The Add, Update and Delete events are self explanatory.

The sixth reason is also rare, but can happen. There are times, let's say for reporting on data from a 3rd party product where we need to be able to access a table from another dictionary as though it is in our dictionary. In this case the methods using execute() and pass through sanScript are not going to work.  So we can create a Combined Dictionary (KB 930350 Secure Link) and transfer the table definition (without referenced resources) to our dictionary.  This technique works well for accessing the data, but if we make any changes using our duplicate table definition, the trigger on the original table will not see it.  You would need to also register a cross dictionary trigger on the duplicate table.

Let me know if this is helpful.

David

04-Feb-2010: Added additional reason (Duplicate table definitions) for table triggers to fail.

Dexterity Training in Orlando (May 10th to 14th 2010)

Dexterity - Click for blog homepageAnother opportunity to learn the foundations of Developing for Dynamics GP is now available. 

Microsoft Dynamics GP's core application user interface is developed using the Dexterity development system.  Knowledge of Dexterity and therefore how Dynamics GP's internals work is fundamental to developing customisations and products that work with Dynamics GP.

Even if you don't plan on developing with Dexterity and wish to use Visual Basic for Applications (VBA) or Visual Studio Tools for Microsoft Dynamics GP, this course is well worth attending.  Having an understanding of how the GP windows are constructed, how table buffers and ranges work, and how to call functions and procedures are just a few of the things that is useful to all developers regardless of the development tool used.

Leslie Vail (MVP) will be instructing the 5 day Dexterity class to be held in Orlando, Florida, USA during the week starting on the 10th of May 2010.  Leslie is an excellent trainer with awesome application and development knowledge and experience.  The course will be fun and extremely educational.

The course is organised through the partner Integrated Business Group (http://www.ibgnet.com/). If you would like more information, contact the training coordinator, Roxanna Alvarez, ralvarez@ibgnet.com or at +1 (407) 677-0370.

This course is a must for anyone wanting to get started in the Dynamics GP development world. See point 3 in my blog posting on How to get started with Dexterity.

For more info see Leslie's blog post: DEXTERITY class May 10th in Orlando  


If you enjoyed the troubleshooting session on the Support Debugging Tool for Microsoft Dynamics GP at the Microsoft Dynamics GP Technical Conference 2009, let it be known that Leslie worked with Mariano and myself into the small hours of the morning to make the session as great as it was. 

Thanks Leslie.

David

What causes an "All call stacks are in use" error?

David Meego - Click for blog homepageAs a Dexterity developer you might have come across the following error:

All call stacks are in use. Cannot start script.

This post will describe what call stacks are (from a Dexterity perspective), how they are used and what causes this error to be generated.

Note: I will start by saying that this topic is covered very well in the Dexterity Programmer's Guide (Volume 2, Part 5, Chapter 24) and also in the Dexterity Help file (search for "Call Stacks", then click on "described").  Thanks to Steve Kubis and the Dexterity documentation team.


A call stack is a mechanism for managing the processing of scripts.  In programming terms, a call stack is a Last In First Out (LIFO) data structure that stores the state of a script (variables, next command to execute, etc.).  When Script A calls a child Script B, the state of Script A is placed (or pushed) onto the call stack while Script B runs.  When Script B is completed, the state is restored (or popped) back from the call stack and Script A continues running from just after the call to Script B.

When Dexterity calls global and form level functions and procedures, all the processing is handled on the single call stack.   This can be visualised as a pile of paper sheets and as each new script runs a new sheet is placed onto the pile and then removed when that script is completed.

However, under certain circumstance Dexterity can execute code which requires its own call stack.  To support this, the Dexterity system has eight (8) call stacks.  One call stack is dedicated to background processing which leaves seven (7) call stacks for foreground use.

There are three types of processes which can start a new call stack being used:

  1. Procedures that are called automatically by Dexterity, such as the global procedures Security and Pathname.
     
  2. RW Functions called by Report Writer calculated fields as User Defined Functions.
     
  3. run script commands which executes the script attached to the change event of the window field specified.

The problem with running out of call stacks and generating a call stack error is usually caused when developers over use the run script command. The two examples below will explain how the call stacks are used with the run script command:

Example 1: Script A

run script 'B';
run script 'C';

In example 1: when Script B is executed a second call stack is used. But once Script B is completed the call stack is no longer needed and the execution returns to the original call stack.  Then Script C is executed in the second call stack.  This sequential calling using the run script command only uses one additional call stack and so does not cause the error condition.

Example 2: Script A

run script 'B';

Example 2: Script B

run script 'C';

In example 2: when Script B is executed a second call stack is used. Script B in turn executes Script C and so uses a third call stack.  This nested calling using the run script command uses an additional call stack for each nested call.  As there are only seven call stacks available for foreground processing, you can only have six levels of nested run script commands.

The following diagram from the Dexterity manuals shows the Background call stack and the seven Foreground stacks.  Note how the seven stacks are all used because of six nested run script commands.

Call Stacks in use 

If a 7th nested run script command is called, an automatically executed procedure is called (by opening a form or table), or a report is run which calls a RW function; the system will have no call stacks available and so produce the error:

All call stacks are in use. Cannot start script.

One example I have seen of this issue was on a maintenance window which had nested run script commands to update fields on the window depending on other fields on the same window (for example: disabling fields depending on a checkbox). When the window used by itself there were no issues. However, when the window was opened by a drill down, there was at least one more run script command and the error occurred.  This shows how using too many nested run script commands might not break the code all the time, but could cause issues when called by different methods.

It is recommended that developers don't nest run script commands more than 3 levels. This is should help avoid the issue from occurring. Other methods of avoiding the error include using functions and procedures rather than run script commands and using the run script delayed command. The run script delayed command starts the specified field change script after all foreground processing is complete and so does not use an additional call stack.


For a related post on this topic where this error is caused by Regional and Language settings see Janakiram's post below. The difference in the control panel settings must be altering the behaviour of the code in such a way to make it attempt to use one more call stack:

All Call stacks are in Use. Cannot Start script

Hope this information is useful.

David

Fixed Asset Integration error: "String was not recognized as a valid DateTime"

Dawn Langlie - Click for blog homepageI recently had a support case, running a Fixed Asset integration with Integration Manager, where we received the following error:

DOC 1 ERROR: System.FormatException: String was not recognized as a valid DateTime.
at System.DateTimeParse.Parse(String s, DateTimeFormatInfo dtfi, DateTimeStyles styles)
at System.DateTime.Parse(String s, IFormatProvider provider)
at System.Convert.ToDateTime(String value, IFormatProvider provider)
at System.String.System.IConvertible.ToDateTime(IFormatProvider provider)
at System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider)
at System.Data.SqlClient.SqlParameter.CoerceValue(Object value, MetaType destinationType)

The date format in both the source file and Microsoft Dynamics GP are set to MM/DD/YYYY.  We verified that the regional settings are set to English (United States) and the Date format is MM/DD/YYYY.  We also verified that the Server Properties in SQL are set to English (United States).

As this integration utilizes eConnect, we then looked at the Identity in the eConnect COM+ Application and this was a different user.  eConnect will look at this user’s Regional Settings to find the Date format.  We changed the Identity to the user that we verified Regional Settings for and the integration is now working without errors.

I hope this helps save time troubleshooting this error.

Dawn

Microsoft Dynamics GP 2010 Beta Released

David Meego - Click for blog homepageThe Microsoft Dynamics GP 2010 Beta code has been released.  This release, previously known as GP "11.0", is the largest release in Microsoft Dynamics GP history with a massive amount of development work and time going into it.  It can be downloaded from PartnerSource using the link below:

Beta Download for Microsoft Dynamics GP 2010 (PartnerSource)

We are excited to announce the newest version to the Microsoft Dynamics GP platform: Microsoft Dynamics GP 2010. Microsoft Dynamics GP 2010 will focus on increasing depth and reach for core functionality, enriching integrations with the Microsoft Office system, extending external connections through Web Services, and ensuring faster Return on Investment (ROI) for customers. This release is the final data model planned for this release along with all the planned features shipping with Microsoft Dynamics GP 2010.

Here is a sampling of some other posts from around the blogsphere:

It is a GREAT Day! (from Pam @ Inside Dynamics GP)

Feature of the Day series (from Inside Dynamics GP team)
Note: This series will have more posts added over time, so please look in on a regular basis.

Microsoft Dynamics GP 2010 Beta Buzz (from Mariano @ Dynamics GP Blogster)

What's new in Microsoft Dexterity 11.0 (from Mariano @ Dynamics GP Blogster)

Inside Microsoft Dynamics 2010: Arabic Version of Dynamics GP 2010 “11”!!!! (Mohammad Daoud shows us how cool the Dexterity development environment is by translating to Arabic.)

I think you will all agree that we have an exciting year ahead.

David

PS: For information on how to translate Dexterity code, have a look at the Translating Dexterity Applications Series.

Removing Extender Data when deleting Transactions or Lines

David Meego - Click for blog homepageI was recently asked to assist a colleague with an Extender case.  The problem was that Extender data was not being removed from the Extender SQL tables when its parent record was deleted.

The issue of Extender data being orphaned when the parent data is deleted is a known issue (KB 906242 see link below) and can be resolved fairly easily:

  • For Version 10.0 onwards you can use the Table Links feature (when editing an Extender object, from the menus select Options >> Table Links).  This allows you to define a parent table so that Extender knows to remove the additional data when the parent record is deleted.
     
  • For Version 9.0 and before, your option was to use a SQL Trigger on the parent table's delete event to clean up the data. Examples of the triggers are included in the attached archive at the bottom of this article.

These techniques work well for Master records (Customers, Vendors, Items, etc.) but do not always work as desired for Transaction records.


The reason Transaction records are different is that they move from table to table as the document moves through the workflow. They move from Work to Open when posted and then from Open to History when fully applied or archived.  Some transactions move straight from Work to History, but still have the same issue.

So if you place the Table Link or SQL Trigger on the Work table, when the transaction is posted and the record is added to the Open table and deleted from the Work table, the Extender data is deleted at the same time.  In summary, this means that the Extender data is lost once the transaction is posted.

This issue is described in KB 967740 (see link below) and provides the solution to add the Table Link or the SQL Trigger to the History table so the data is only removed when the transaction gets removed from History.

This solution prevents the Extender data from being removed prematurely but it does not handle the situation when Transaction Lines or the entire Transaction is deleted by the user while it is still unposted and stored in the Work tables.

So what is needed in addition to the Table Link or SQL Trigger on the History table, is a method to handle when a transaction is deleted by the user from the Work table which will not be fired when the transaction is posted.  This means we need to use events at the user interface instead of at the table level.

So we can use any of the customisation tools which work at the user interface. For our example we will use Visual Basic for Applications (VBA).

The concept behind the code is to use VBA to capture the delete line and delete transaction events via the Modal Dialogs and then use ActiveX Data Object (ADO) to open a connection to SQL Server and execute the appropriate Transact-SQL delete statements to remove the data from the appropriate tables.

Below is a list of the tables used to store data for normal Extender Windows:

Dexterity Technical Name SQL Table Description
PT_Extender_Window_Key_Values EXT00100 Stores the Mapping between the parent data's keys and the Extender key
PT_User_Window_Field_Strings EXT00101 Stores String values based on the Extender key
PT_User_Window_Field_Dates EXT00102 Stores Date values based on the Extender key
PT_User_Window_Field_Numbers EXT00103 Stores Numeric (Currency & Integer) values based on the Extender key
PT_User_Window_Field_Times EXT00104 Stores Time values based on the Extender key

Below is a list of the tables used to store data for Extender Detail Windows:

Dexterity Technical Name SQL Table Description
PT_UD_Detail_Window_Lines EXT00180 Stores the mapping for the line sequence numbers for the Extender key
PT_Detail_Window_Dates EXT00181 Stores String values based on the Extender key and line sequence
PT_Detail_Window_Dates EXT00182 Stores Date values based on the Extender key and line sequence
PT_Detail_Window_Numbers EXT00183 Stores Numeric (Currency & Integer) values based on the Extender key and line sequence
PT_Detail_Window_Times EXT00184 Stores Time values based on the Extender key and line sequence
PT_Extender_Detail_Window_Key_Values EXT00185 Stores the Mapping between the parent data's keys and the Extender key

 


The example code uses the Inventory Transfer Entry (IV_Transfer_Entry) window and includes two different examples. This is so we can demonstrate the code needed for both normal Extender Windows and Extender Detail Windows.

  1. Adding normal Extender Windows against the Transaction Line and Transaction Header
     
    Extender Windows.xml - Contains Extender Settings for the Extender Windows IVTRF_1 & IVTRF_2.
    IV_Transfer_Entry (Extender Windows).Package - Contains VBA code to delete Extender data when deleted by the user.
    Extender Windows.sql
    - Contains example SQL Triggers on work tables - For reference only, should not be used for live system.
     
  2. Adding an Extender Detail Window against the Transaction Lines
     
    Extender Detail Window.xml - Contains Extender Settings for the Extender Detail Window IV TRANSFER FORM.
    IV_Transfer_Entry (Extender Detail Window).Package - Contains VBA code to delete Extender data when deleted by the user.
    Extender Detail Window.sql
    - Contains example SQL Trigger on work table - For reference only, should not be used for live system.
     

NOTE: The SQL scripts provided above are examples to show how SQL triggers can be used to remove Extender data when a record is deleted from a SQL table.  They are coded to trigger on the Work tables to demonstrate the issue when posting a transaction removes the data. They should NOT be used in a live system.  They can be modified to work with history tables if required for v9.00 systems, but for v10.00 systems we suggest using the Table Links feature with the History table.

Example v10.0 Extender Settings and VBA code for the Inventory Transfer Entry (IV_Transfer_Entry) window is attached to the bottom of this article.

For related information please see the following Knowledge Base (KB) articles:

The associated Extender record is not deleted when you delete a Microsoft Great Plains record (KB 906242) Customersource

Extender data is removed from the EXT00100 table when a batch is posted in Microsoft Dynamics GP 10.0 (KB 967740) Customersource

The bottom line is that for the system to work 100%, you need both VBA (or equivalent) code to remove the Extender data when the user deletes the transaction from the Work tables AND you need to have a Table Link (or SQL Trigger) on the History table to handle if the transaction is removed from history.

Post a comment if you find this information and sample code useful.

David

01-Feb-2010: Added extra explanations about SQL Trigger Scripts included in attachment.

Announcing Microsoft Dynamics Convergence 2010

David Meego - Click for blog homepageMicrosoft Dynamics Convergence 2010

OK, so I am a little late in announcing Microsoft Dynamics Convergence 2010, but I was away for a while.  However, this is the first article about the upcoming conference on this blog.  So ....

Join us for Convergence 2010 in Atlanta, April 24th - 27th. Attending Convergence provides you ample opportunities to network with a targeted group of business professionals and to discover how you can get the most value from your Microsoft Dynamics solutions – and how to increase your business potential. Register today to take advantage of US$300 per person Early Bird savings off the regular registration fee. For more information, click here.

The video below is a overview of Convergence Atlanta 2010:

For more videos about Convergence and other subjects important to the Dynamics, go visit the Microsoft Dynamics Community channel on youtube.

Here are some other posts from around the blogsphere:

Register now for Convergence 2010 in Atlanta (from Mariano Gomez)

Convergence 2010 Atlanta Registration Starts Today! (from Mark Polino)

Volunteering at Convergence 2010 (from Mark Polino)

Make sure you register sooner rather than later.

David

Increasing the Microsoft Dynamics GP 10.0 Homepage Font Size

David Meego - Click for blog homepageI was recently asked if it was possible to change the fonts on the Microsoft Dynamics GP 10.0 Homepage.  A customer had asked if they could be made a little bit bigger as they were hard to read at the resolution that the machine was running at.

So I decided to have a quick look to see what was needed. The homepage itself for the current user is stored in the temp folder for that user, for example:

C:\Users\<username>\AppData\Local\Temp\HomePage.xml

This xml file is generated by Dynamics GP depending on the homepage settings in the application. It in turn references the XML Style Sheet (.xsl) file in the Background subfolder of the application installation folder.

C:\Program Files\Microsoft Dynamics\GP\Background\HomePage.xsl

This style sheet file then references the Cascading Style Sheet (.css) file in the same folder. 

C:\Program Files\Microsoft Dynamics\GP\Background\HomePage.css

It is this HomePage.css file which contains the definition for the fonts used on the homepage.

Note: Examples of the already altered files for HomePage.css and PreviewPane.xsl are contained in the attachment at the bottom of this post.

If you wish to make the changes yourself rather than use the files provided.... Then make a copy of this original HomePage.css file and call it HomePage Normal.css.  This is your backup to restore the default settings if necessary.

You can then make a second copy of the file and call it HomePage Big.css. Then open the HomePage Big.css with Notepad.exe and perform a series of find and replaces to change the font sizes by increasing them by 2 points. 

You need to start with the largest font size and work down to the smallest:

Find String  Replace String 
13pt  15pt 
12pt  14pt 
11pt  13pt 
10pt  12pt 
9pt  11pt 
8pt  10pt 

Once the changes are complete and file saved, you can delete the original HomePage.css file and copy HomePage Big.css and rename it as HomePage.css.  To restore, just delete HomePage.css and copy HomePage Normal.css and rename it as HomePage.css.

The AreaPage.xsl file used when displaying the Area Pages also uses the HomePage.css file, so the font changes are applied here as well.

The  PreviewPane.xsl has some font definitions and is used for the preview pane when looking at lists. It can be altered in the same way to produce PreviewPane Normal.xsl and PreviewPane Big.xsl files.

Note: Examples of the already altered files for HomePage.css and PreviewPane.xsl are contained in the attachment at the bottom of this post.

For a related post, Mohammad Daoud has an article which shows how the homepage and be "removed" by replacing it with a logo image if desired:

How to change GP 10.0 Homepage??

Hope you find this useful.

David

VBA - Determining the company name selected in the Company Login window

Patrick Roth - Click for blog homepageA question came up a while back where the user wanted to know what company the user was logging into in order to give them a message depending on the company selected.

The specific issue was that VBA cannot get the name of the company from the DDL (drop down list), it can only give you the position.  Also the position in the list doesn't have any bearing on the company id of the company displayed.  It is just an ordered list by alphanumeric sorting by the Company Name field.

The question wasn't specific to when exactly the user needed to see this message.  When initially I read the question and based on how it was posed, it seems they wanted to know right when the DDL was selected.  But it could have been when the OK button was pressed and it also could be just after they log in.

Given that the technique used would be different, I will present both solutions.

Situation 1

For this solution, we will assume that the programmer needs to know the company after the user logs into Dynamics GP in order to give them some information or take a specific action.

The easiest way to do this it to use a Window_AfterClose() event on the Company Login window (Switch_Company form in Dexterity) and use the UserInfoGet object to retrieve the company logged in.

In the VBA code sample below, before the window opens we see what the current company is.  We could either being logging into Dynamics GP for the first time or just switching companies.  And if switching companies, we might press Cancel or just re-select the same company.  So by checking the previous logged in company and comparing we only show our message if the company we are going to really changed.

VBA Code for Company Login window

Situation 2

While the solution given for the first situation is OK if we want to let the user log in, it is possible that we might want to give a message before the GP login occurs.  Or potentially stop the user from being able to log into the company for some specific reason.

If that is the case, we would then need to know the selected company before the Company Login window was closed.  The only way to do that is to know the company name selected in the Company DDL.

Because we cannot directly read the name from the Company DDL field, we have to pull the information directly from SQL in the order that Dynamics is displaying it.  Then we'd know the company being selected and could act upon that.

VBA Code for Company Login window 2
 
Depending on your exact needs; either one of these solutions might work for you or at least get you started.
 
Best Regards,
Patrick
Developer Support
Vote for Barbie as a Computer Engineer

David Meego - Click for blog homepageVote for Barbie's next careerNow is the time for action!!! 

We need you.... OK, Mattel does.

It seems that Barbie is looking for a new career and we need your help to vote for her to be a Computer Engineer.

I found out about this career vote by reading my friend's, Catherine Eibner, funny post on the topic: Barbie as a Computer Engineer?.  I am surprised that there is no option for Backhoe Operator after reading her article.

So please vote by clicking on the badge above or visiting: http://www.barbie.com/vote/ before the 12th February when the results will be published.

David

Blast from the Past - The Inside Track Series Concludes

David Meego - Click for blog homepageI hope you have enjoyed the Blast from the Past - The Inside Track Series.

To make life simpler, I have attached a zip file with all 10 of the original Inside Track pdf files.

To finish off, here are some comments from the original author, Karl Gunderson:

Karl Gunderson“You want to republish what?” was the first thought that went through my head when I received an e-mail from David.  I sort of knew David from the distant past, but I’ll bet we were as surprised as the other that we are both still working here.  Here being Microsoft Business Solutions, the people formerly known as Great Plains Software from Fargo, North Dakota.  I’m now a developer working on Dynamics AX and David is still breathing fire into Dynamics GP (I looked over his blog after receiving the e-mail!).  So David wants to dredge up those moldy old columns from umpteen years ago and republish them.  I guess he’s on a nostalgia kick, I’m thinking.

I read over those old columns, columns that you have now had the, shall we generously call it a “pleasure”, to read yourselves, and found that they weren’t all that awful.  They did touch on topics that are still relevant today.  They did include some useful stuff like code and lightweight development methodologies.  I didn’t notice too many mistakes; thank goodness for good editors!  And so I gave David the oki-doki.

I guess I mentioned in the first column that I’d worked in both customer and partner-like organizations.  From the inside, we are working on the next version, the next greatest thing.  But I do realize that you still have a continuity of service and product that you need to maintain.  You have real customers and users who depend on this stuff we call software, working day in and day out.  And, there is a whole crop of new you out there that are helping those people; you who have never heard of a command line editor or only vaguely know what ActiveX means.  We all depend on progress that those who came before us made.  We continue to make progress and provide the basis for the next crop.  I hope these columns have played a small role is building that road to a new software future.  Engage, Scotty!

Karl

P.S. Scotty (James Doohan) was the engineer (surely a big part of his job would deal with software, right?) on the original Star Trek series.  The overly dramatic Captain Kirk (William Shatner) would order the good ship Enterprise into motion (into the future, at warp speeds) with a proclamation like “Engage, Scotty!”  It seemed fitting.  My apologies for stating the obvious if you got the reference.

The newsletters are available as a zipped attachment at the bottom of this article.

David

More Posts Next page »
Page view tracker