Dynamics GP 2010 R2 Database SDK – Siva


I was in fact awaiting Sivakumar’s post about the new section that he has been working on. I got the privilege to go thru’ this first before his post went public.

Siva’s new section is all about GP 2010 R2 SQL Objects (Tables, DBs, Stored Procedures, Views, etc.). Like the one we have in MS Word documents that can be accessed from GP SDK, this is also an interesting concept and also very informative for all developers out there, who may not have access to SQL Server on a real time.

Read his post here, Dynamics GP 2010 R2 Database SDK, and share your thoughts with him. 

I am sure this is going to be of immense help for all of us.

VAIDY

Advertisement

GP Homepage Layout Mass Update – Thru’ SQL


I love SQL. Simply because, it eases lot of pain in doing some redundant work.

When you create a user, by default, GP creates the following segments on his/her homepage:

1. To Do (Reminders/Tasks)
2. My Reports
3. Microsoft Outlook
4. Quick Links
5. Connect (links to Online Resources such as CustomerSource, Forums, Blogs, etc.)
6. Metrics (quick dashboards for users)

All of the above work perfectly, but at some stages (especially when you are working on a GP Terminal Server) some of these components would halt GP for a while, not allowing users to do anything.

One classic example is Microsoft Outlook. We recently migrated our Email Services to Microsoft Office 365. For those users who use Thin Client to on their day-to-day job, Terminal Server is THE destination. Quite obviously, Terminal Server has got Outlook installed.

Before Office 365, Outlook profile used to connect to our on-premise Exchange Server. After migration, we had to change the profile from Exchange Server to Office 365 hosting server.

Whenever a user logs on to Terminal Server and opens GP, GP will halt for at least 3-5 mins to get this Outlook configured. I am getting calls from users (yes, even now) that their GP session does not work and they are not able to do anything. Following icon shows up on their taskbar when this happens:

It didn’t take me much time to realize that all these users had added Microsoft Outlook on their GP homepage.

“Do we really need Outlook on GP homepage?” is a question to be asked to oneself. Yes, Microsoft has integrated your ERP with one of the most used product by maximum business users. Agreed. But is that alone a reason for you to use it? Let’s not get into that argument in this post, anyways.

I had to take a stand and remove Microsoft Outlook from those users’ homepage. But then, I don’t know, right now, about how many users out of 100+ total users have added Outlook on their homepage.

Certainly not without the help of a SQL query.

The table where this information has got stored is SY08100 (Technical Name: syHomePageLayout). In this table, the column SectionID denotes the sections which are available for a user to add to his/her homepage. Following is the legend:

1 – To Do (Reminders/Tasks/Cues)
2 – Microsoft Outlook
3 – Metrics (quick dashboards for users)
4 – My Reports (links to users’ favorite reports and smartlists)
5 – Quick Links (links to users’ frequently used windows)
6 – Connect (links to Online Resources for GP such as Forums, Blogs, etc.)

Typically, for each user, this table will contain 6 rows, each row denoting each of above section. SY08100 also contains a column named Visible. This denotes whether or not to show a particular section on GP homepage.

For instance, if user SA has setup his GP homepage to show To Do, My Reports & Quick Links to show up, the following will be SY08100 records:

So, if I want to hide Microsoft Outlook from all users’ homepage, I just have to execute the following SQL query on DYNAMICS database:

UPDATE SY08100 SET Visible = WHERE SectionID = 2

We must also understand one thing. Users can always add this again thru’ Customize this page… option. So this is NOT A PERMANENT SOLUTION.

Whenever there is a necessity, as in my case, you can certainly rely on this SQL method to do a homepage layout mass update.

VAIDY

Test Company Posting Journal File Destinations


One thing we all must remember while restoring a Live Company DB onto a Test Company DB is, that several places in GP tables, Company ID is stored. We have a SQL Script that will search ALL tables and ALL columns that contain the Inter ID (SQL ID for each GP database) and replace the live DB ID with test DB ID.

This post explains some specific cases where the Posting Journals of all transaction types are destined to a text file. Typically, in a multi-company environment, consultants would setup the path for all Posting Journals with the respective company Inter ID (or any folder name that uniquely identify each company).

I will explain you an ideal scenario, where this poses an issue.

I would restore live backup onto a Test Company and run the SQL script that will replace all live company ID references to test company ID. But my Posting Journals File destination is a simple string value, something like below (I have taken Purchase as a sample series):

:C:Journals/[CompanyID]/Purchase/[JournalReportName].txt

So if my live company ID is, for instance, VMLIVE, then the above path would like this:

:C:Journals/VMLIVE/Purchase/JournalReportName.txt

Whenever I post a purchase transaction, my Posting Journal detail would go and get append on this file, which I can audit at any point of time.

Now, consider that my Test Company ID is VMTEST. When I restore my live backup onto my test company and run the SQL script which replace live company reference with test company ID, everything would get fixed except this. Since the value stored in File Destination field in the Posting Journal Destinations table (SY02200) is NOT JUST the company ID, but the above Filename with Path.

After restoration and I post a purchase transaction on my test company, the posting information get appended on the file JournalReportName.txt on the path C:\Journals\VMLIVE\Purchase, which is WRONG. It’s not just wrong. Your posting journal file gets dumped with test entries as well as live entries. If any client audits the Posting Journal files as part of their internal process(es), then it’s a big trouble.

In such scenarios, where all posting journals are destined to a text file on a path identified specifically by a company ID or name, the GP Administrator must make sure that the field FILEXPNM (File Export Name) on table SY02200 (Posting Journal Destinations) must be properly updated before we post any test entires. Below is the simple UPDATE statement which would fix this:

UPDATE SY02200
SET FILEXPNM = REPLACE(FILEXPNM, ‘[LiveCompanyID/Name]‘, ‘[TestCompanyID/Name]‘)

Where [LiveCompanyID/Name] denotes the value which identifies your Live Company and [TestCompanyID/Name] denotes the value which identifies your Test Company.

VAIDY

SQL Tip: Find Table(s) Having A Particular Column


This SQL query is my savior for a long time now. Thought I would just share it with all budding SQL developers.

Q: How to find the table(s) which contain a particular column which I know?
A: Below is the query that would do the trick.

SELECT name 
FROM sys.objects 
WHERE object_id IN 
(
SELECT object_id 
FROM sys.columns 
WHERE name = [columnname] –Column which you would want to locate
)

This query will return all tables which contains the specific column. And this query also would save your time immensely.

VAIDY

Don’t update "Batch Status" thru’ SQL when users are logged on


A user complained about a batch not being able to be posted. The error message is something like this: This batch is currently receiving transactions.

Normally when a user complains about something like this, a GP Administrator or Consultant’s immediate step is to check what the *Batch Status* field holds in SY00500 (Batch Header) table. The legend for this field says:

0 – Available – BATCH_AVAILABLE
1 – Marked to Post – BATCH_POSTING
2 – Marked to Delete – BATCH_DELETING
3 – Marked to Receive – BATCH_RECEIVING
4 – BATCH_DONE_POSTING
5 – BATCH_PRINTING
6 – BATCH_UPDATING
7 – BATCH_POSTING_INCOMPLETE
8 – BATCH_PRINTING_INCOMPLETE
9 – BATCH_UPDATING_INCOMPLETE
10- BATCH_RECURRING_INCOMPLETE
11 – BATCH_POSTED_WITH_ERROR

And quite apparently, in my case, it was 3. i.e. BATCH_RECEIVING. It’s very easy to update this field back to ZERO that denotes BATCH_AVAILABLE, so user can post it.

I could have also done the same thing. But I did not. I just wanted to make sure that this batch indeed did not receive any transactions. How do we identify whether a batch is receiving transactions or not? That I will address in another post.

This one is intended to caution a Consultant or Administrator NOT to update *Batch Status* thru’ SQL for any batch which is marked as BATCH_RECEIVING when users are logged on.

It would break a valid transaction being saved in this particular batch. When a batch receive transactions, GP locks this batch from getting posted only by updating the *Batch Status* field with BATCH_RECEIVING. By changing that from back end, we are risking batch getting corrupted.

Tell the user that he/she has to wait. And wait till users log off from GP. And then check whether the *Batch Status* becomes BATCH_AVAILABLE. In case it is not, then you update it thru’ SQL.

It is worth waiting for sometime than trying to clear a mess. I take this opportunity to insist again: SQL is not ALWAYS an appropriate approach for issues that we face in GP.

UPDATE: David has sent me a link, which quite obviously I missed mentioning here. How did I miss this? We do have a way to release stuck batches without logging off users.

VAIDY

Stored Procedure as Data Source in PowerPivot – Issue & Solution


I am working on a PowerPivot based analysis design and my data source is a SQL Stored Procedure which does the following:

1. Inserts set of records from one DB into a Table Variable.
2. Inserts similarly structured set of records from another DB into the same Table Variable.
3. Finally retrieves records by SELECT…GROUP BY… statement based on necessary criteria.

The above is to ensure that I don’t end up troubleshooing Temp table issues or data redundancy or performance issues for that matter.

PowerPivot understands the above stored procedure very clearly and it also validates the execute query without any issues. It even shows the result set in preview. But it throws the following error message after all the steps involved in setting up SP as data source:

The above error message is quite less informative. I initially thought Stored Procedures are not properly supported by PowerPivot (how silly I am…!!!). But I just gave myself some more time to search forums as usual. After all, I spent almost a day in getting that Stored Procedure completed with 100% accurate results.
The following is the SIMPLE FIX to that menacing issue:
Yeah that’s it. SET NOCOUNT ON is that simple fix. Now my PowerPivot understands this SP and works merrily.
The Post I got this answer from: PowerPivot and Stored Procedure as a SQL Source.
The answer is given by Microsoft Product Team and that was conveyed by Lisa Liu CSS, a Microsoft Moderator.
The reason for why we ought to set NOCOUNT ON is given in the same post by Devarajan KM. The reason is: Set NOCOUNT to ON so that you get only one result set arrived after execution.
VAIDY

Analytical Accounting Menu Master Table (SY07110) Records Multiplying – Bug & Workaround


This one is another SY07110 (syMenuMstr) table issue.

For the past 1 week, users were complaining about GP slow down as soon as they select a company and click OK. The delay was anywere between 30 seconds to 1 minute, which is quite huge, considering the fact that GP is suppose to get initiated within 3-5 seconds maximum.

We have two different launch files; those users who are not suppose access AA and those who access AA. This delay was reported by only AA users. And that eased my debugging task out.

Troubleshooting started by taking a SQL Profile exactly at the time of selecting a company and clicking on OK. After painfully long time, GP got initiated with all Menu and other startup objects. I stopped SQL Profiler and noticed the following piece of SQL query being executed for as many as 143 times, which in total resulted in 4730 records:

The above query is same except some of the fields. But all these SQL SELECTs where targeting the same product; AA (CmdDictID = 3180).
Quite shockingly, I had 4730 records in SY07110 for Dictionary ID 3180, i.e. AA.
So how to solve this? Simple. I took a backup of this table (just for precaution) and executed the following SQL query:
DELETE DYNAMICS..SY07110
WHERE CmdDictID = 3180
It removed all 4730 records for AA module. I then launched GP. Bingo. It’s getting initiated in as long as 3 seconds.
The story does not end here. For the first time SY07110 table gets inserted with 33 records for AA module. As and when a user launch GP, with AA module, it inserts exactly ONE additional row onto SY07110 table.
Now this certainly looks like a bug.
So what’s the solution? Time being, I have to write a scheduled SQL job which will execute the above DELETE query on a weekly or daily basis.
I am not sure who else is currently facing this issue. If any of you people have this issue, then at least you have a workaround.
I am planning to raise a Support Ticket with MSFT team if no one out there gets back to me with a solution and make sure that this is not a bug as such.
VAIDY

Getting Month Numbers between two dates in T-SQL


I literally had to spend around an hour to crack this code, with some little help from my best geek friend, GOOGLE, of course.

Issue is this: I wanted to get Month in Numbers (Jan = 1, Feb = 2, etc.) that exist between two dates. For instance, if my date range is 1-Jan-2011 to 31-Mar-2011, then I should find and retrieve the months Jan, Feb and Mar as 1, 2 and 3 respectively.

After much much toiling and reading some stuff online, the following is what I got for myself:

—–

;WITH Numbers (Number) AS
(SELECT ROW_NUMBER() OVER (ORDER BY OBJECT_ID) FROM
sys.all_objects)
SELECT MONTH(DATEADD(MONTH, Number – 1, ‘2011-01-01’)) Month_Number
FROM Numbers
WHERE Number – 1 <= DATEDIFF(MONTH, ‘2011-01-01’, ‘2011-03-31’)

—–

IMPORTANT: Make sure that you have more than 12 records in sys.all_objects table, which by default SHOULD have.

I hope this code piece is useful for some who have got similar requirement.

VAIDY

T-SQL "UNION" Vs "TABLE variable"


Very recently I learned this. And what a change it has made to all of my SQL based projects! I am sure people who are hardcore SQL programmers would already know this. Thought of sharing this for those who would want to know something interesting.

I had a SQL Stored Procedure that is about to retrieve records of a same table from two different databases. The usual approach was something like below:

SELECT [column_name_1], [column_name_2], [column_name_3], …
FROM [db_name_1]..[table_name]

UNION

SELECT [column_name_1], [column_name_2], [column_name_3], …
FROM [db_name_2]..[table_name]

This was working till these tables contained records less than 30000 rows. And it started taking significantly unacceptable time (like 10-15 seconds). I then thought of creating a temporary table and dump records from one DB then from other. There is a potential issue in that, in the form MULTI-USER environment. When two different users invoke this stored procedure at the same time, this temporary table must cater for both. I was not really sure about how I can address this.

Then came this idea of using TABLE VARIABLE. It’s like a Structure in C++. This is how I modified my stored procedure:

DECLARE @TABLE_NAME TABLE
(
Column_1 DATATYPE,
Column_2 DATATYPE,

)

INSERT INTO @TABLE_NAME (Column_1, Column_2, …)
SELECT [column_name_1], [column_name_2], …
FROM [db_name_1]..[table_name]

INSERT INTO @TABLE_NAME (Column_1, Column_2, …)
SELECT [column_name_1], [column_name_2], …
FROM [db_name_2]..[table_name]

SELECT Column_1, Column_2, …
FROM @TABLE_NAME

After this, the program started taking around 2-5 seconds with more than 50000 records to handle. Not to forget, this program contained several grouping and calculations.

I don’t have to worry about delay and also TEMP TABLE issues that are potentially disastrous. I am still not sure how this is handled in terms of memory allocation. What happens after this program completes it’s process, is also a factor that I am yet to figure out.

But, so far, I have found this as one of the best methods in recent times.

VAIDY