Welcome to MSDN Blogs Sign in | Join | Help

Please check out David's post for links to the fixes.

http://blogs.msdn.com/excel/archive/2007/10/09/calculation-issue-update-fix-available.aspx

1 Comments
Filed under:

This same calculation issue affects Excel Services, and is being addressed concurrently.

http://blogs.msdn.com/excel/archive/2007/09/25/calculation-issue-update.aspx

1 Comments
Filed under:

Dear Friends and Family,

I recently accepted the challenge to raise funds to support the JDRF Northwest - Nordstrom Beat the Bridge in its efforts to find a cure for diabetes and it's deadly complications.  Every day 35 more children are diagnosed with diabetes. This diagnosis means a lifetime of insulin shots and extremely devastating complications, not to mention the fact that diabetes on average shortens a person's lifespan by 15 years and the only hope is a cure. The Juvenile Diabetes Research Foundation (JDRF) is the largest private funder of diabetes research in the world and since it was founded in 1970, has awarded over $900 million to diabetes research.  JDRF has implemented a campaign to raise $1 billion over the next five years in order to accelerate the cure for diabetes.

Last year's Beat the Bridge event raised a record $1,000,000 for diabetes research. This year, our goal is to BEAT $1,130,000 for research!  On May 20 the Nordstrom Beat the Bridge to Beat Diabetes run and walk to benefit the Juvenile Diabetes Research Foundation will take place.  I will be there because I want to find a cure for diabetes for the 21 million Americans who have to live with this disease.   

Please help support me in this important fundraising event by contributing generously to the JDRF Northwest - Nordstrom Beat the Bridge. Your tax-deductible contribution will fund the world's leading diabetes research aimed at finding a cure. It is faster and easier than ever to support this great cause - you can make your donation online by simply clicking on the link at the bottom of this message. If you would prefer, you can also send your tax-deductible contribution to the address listed below. More information on the JDRF Northwest - Nordstrom Beat the Bridge and its programs can be found at beatthebridge.org.  

Whatever you can give will help.  It all adds up! I greatly appreciate your support and will keep you posted on my progress.

Sincerely,

LuisBitencourt-Emilio

To donate online, click on my Personal Page.

The Excel services team is looking for companies that are using Excel services and are willing to share their feedback with the team.

 

Feedback can be in the form of visits to the customer sites, conference calls or special events that will be organized in Redmond or in Europe.

 

If you are interested please contact Dany.Hoter@microsoft.com

Another one of our prolific Excel Services testers has started up a blog here: http://blogs.msdn.com/sherder/ 

Go check it out!

   

I've been a little dark on the blog lately in order to focus 100% on planning for O14, but I'll be back soon!

 

0 Comments
Filed under:

Microsoft Office is looking for talented developers to work on cutting edge web-based technologies that integrate with Excel and Access. It’s a great opportunity to work on cool new features and build great products.  You may have already heard about Excel Services that we shipped with Office 2007 (if not you can read more here http://office.microsoft.com/en-us/sharepointserver/HA101054761033.aspx and here http://msdn2.microsoft.com/en-us/library/ms519581.aspx) and we’re building on that story as well as pursuing some other new ideas.

 

If you know someone who might be interested in the position, please contact rmcgrath@microsoft.com. For more info, check out this job listing: http://members.microsoft.com/careers/search/results.aspx?FromCP=Y&Keywords=HA101054761033

Make sure and mention you saw the posting through my blog!

0 Comments
Filed under:

Technet now has some interesting tutorials for Excel Services.

 Check them out at http://technet2.microsoft.com/Office/en-us/library/eea3ace8-0863-429a-b1e8-041254ed2fc41033.mspx?mfr=true

Enjoy!

3 Comments
Filed under:

From yours truly:

Summary: Optimize version 1 of the Excel Services programmability framework to extend Microsoft Office Excel 2007 and Excel Services functionalities to work with SharePoint lists, query tables on Excel Services, external workbook references, SQL write-back, and user-defined functions (UDFs).

 

Link: http://msdn2.microsoft.com/en-us/library/bb267252.aspx

 

NOTE: I already caught a few mistakes that the editing process introduced (like the one in the summary about working with UDFs being an "extension")... but the content should still be intact :o)... I'll go over it and make some requests to clean it up when I get a chance.

NOTE 2: I just found out that the article isn't supposed to be published yet, hence the mistakes I've been catching.  The article that's live is a Draft copy... we're just going to leave it up and replace it with the final version once that's ready which should only take a few days.

As I alluded to earlier, one way to overcome the limitation that array formulas do not dynamically resize to fit the dimensionality of the data being returned by your UDF is to use paging.

Here is a simple way of enabling paging, without having to modify any existing UDF code (you could also use this same code as part of a helper function, though you'd need to add the page/rows parameters to your UDF signature).

To use it in your workbook just wrap the call to the UDF with the pagination UDF.  So when before you might have had as your array formula:

{=getBDCData("SharedServices1", "AdventureWorksDWInstance", "Product")}

Now you use:

{=paginate(getBDCData("SharedServices1", "AdventureWorksDWInstance", "Product"), 50, 1)} 

Note: As you'll notice this is far from the most efficient/performant way of doing this! But it is the easiest and only one that doesn't require modifying the original UDFs. If you have time, you should consider building the pagination into the UDFs themselves, so you only query the data source for the rows you are going to display instead of grabbing every row and later determining the ones you care about.

/// <summary>

/// Paginate the data in the object array passed in

/// </summary>

/// <param name="data">Object[,] with original data</param>

/// <param name="rows">Number of rows per page</param>

/// <param name="page">Current page number</param>

/// <returns></returns>

 [UdfMethod(IsVolatile = true)]

public object[,] paginate(object[,] data, int rows, int page)

{

    if ((data == null)||(data.Rank != 2))

        return data;

 

    object[,] results = new object[rows, data.GetLength(1)];

 

    for (int i = (page - 1) * rows;

         (i < (page * rows)) && (i < data.GetLength(0));

         i++)

    {

        for (int j = 0; j < data.GetLength(1); j++)

        {

            results[i - ((page - 1) * rows), j] = data[i, j];

        }

    }

 

    return results;

}

One of the coolest (only?) SharePoint external data features is the Business Data Catalog (BDC).

The BDC is brand new with SharePoint 2007, and is not yet fully integrated into Excel and Excel Services... though, if you've read one or two other entries in this blog you've probably figured out where I'm going with this :o)

Here's a pretty simple UDF that will take a BDC instance name, entity name, and will return the data associated with it.

Without further delay... just call the UDF below in an array formula in your workbook as usual (e.g. "{=getBDCData("SharedServices1", "AdventureWorksDWInstance", "Product")}")

PreReq: I used the Adventure Works DW BDC sample from http://msdn2.microsoft.com/en-us/library/ms494876.aspx ... you'll need to set up the BDC yourself as well to use this UDF.

PS: Sorry about the horrible formatting... It's a pain refactoring to get the code to look half-way decent on this blog.

/// <summary>

/// Gets data from the entity of the specified BDC instance.

/// </summary>

/// <param name="SSPName">Shared Services Provider Name</param>

/// <param name="BDCInstanceName">BDC Instance Name</param>

/// <param name="entityName">Entity Name</param>

/// <returns>Results array</returns>

[UdfMethod(IsVolatile = true,

           ReturnsPersonalInformation = true)]

public object[,] getBDCData(  string SSPName,

string BDCInstanceName,

string entityName)

{

    object[,] results = null;

    SPSite site = null; 

 

    try

    {

 

        // Impersonate the current user viewing EWR.

        // (See previous Blog post on user impersonation)

        using (WindowsImpersonationContext wiContext =

                                           impersonateUser())

        {

            site = new SPSite(serverName);

 

            try

            {

                // Need to set this so we can grab instance

                SqlSessionProvider.

                Instance().

                SetThreadLocalSharedResourceProviderToUse(

                Microsoft.Office.Server.ServerContext.

                GetContext(site));

            }

            catch (System.Exception ex)

            {

               // Ignore the exception if a provider

               // is already set.

            }

 

            // Get the sample Adventure Works instance

            // For XML of this instance see:

// http://msdn2.microsoft.com/en-us/

            // library/ms494876.aspx

            LobSystemInstance advWorks =

                                ApplicationRegistry.

                                GetLobSystemInstanceByName(

                                             BDCInstanceName);

 

            // Get the entities

            NamedEntityDictionary entities =

                                advWorks.GetEntities();

 

            // Get requested entity

            Entity prodEntity = entities[entityName];

 

            // Get entity Filters

            FilterCollection fc =

                               prodEntity.GetFinderFilters();

           

            // Enumerate results

            IEntityInstanceEnumerator

                               prodEntityInstEnumerator =

                               prodEntity.

                               FindFiltered(fc, advWorks);

 

            // Convert it to a DataTable

            EntityDataTableAdapter dataAdapter =

  new EntityDataTableAdapter(

      prodEntityInstEnumerator);

            System.Data.DataTable resultTable =

                               dataAdapter.EntitiesAsDataTable;

 

            // Define dimensions of results array

            results = new object[   resultTable.Rows.Count,

resultTable.Columns.Count];

 

            // Get the data from the DataTable into object[,]

            int i = 0;

            foreach (System.Data.DataRow currRow in

                                            resultTable.Rows)

            {

                int j = 0;

 

                foreach (object currField in

                                            currRow.ItemArray)

                {

                    results[i, j] = currField.ToString();

                    j++;

                }

 

                i++;

            }

        }

    }

    catch (System.Exception ex)

    {

        results = new object[1, 1];

        results[0, 0] = ex.Message;

    }

    finally

    {

        if (site != null)

           site.Dispose();

 

        SqlSessionProvider.

        Instance().

        ResetThreadLocalSharedResourceProviderToUse();

    }

 

    return results;

}

Here are a few books being worked on about Excel Services:

http://www.amazon.com/Beginning-Excel-Services-Liviu-Asnash/dp/0470104899/sr=8-1/qid=1168539718/ref=sr_1_1/105-2258527-0791610?ie=UTF8&s=books

http://www.amazon.com/Professional-Excel-Services-Shahar-Prish/dp/0470104864/sr=1-1/qid=1168539759/ref=sr_1_1/105-2258527-0791610?ie=UTF8&s=books

And a book on Sharepoint that has a whole chapter dedicated to Excel Services:

http://blogs.msdn.com/edhild/pages/pro-sharepoint-solution-development-combining-net-sharepoint-and-office-2007.aspx

I've read a few of the DRAFT chapters in those books and they should be a big help if you're getting started with Excel Services!

1 Comments
Filed under:

MSDN has created a forum for Excel Services related discussion, you can find it at: http://forums.microsoft.com/MSDN/ShowForum.aspx?ForumID=1208&SiteID=1

We're working on a more readable shortcut, and it's empty as of right now but you can expect the content to grow and there will be folks directly related to Excel Services development involved in answering questions.

Enjoy!

0 Comments
Filed under:

 <UPDATE: Reworded the post to stay away from any legal issues :o) >

We are currently working on planning for the next version of Excel Services and I would greatly appreciate any v1 feedback as well as requests you would like to see implemented in v2. I want to focus on existing Excel functionality that you would like to see on the server, integration with other MS technologies, or very generic ideas/scenarios you would like to enable.

If you have something in mind feel free to post a comment on this page.

A huge thanks in advance for your feedback!

7 Comments
Filed under:

As you have noticed, many of my samples below use an Array Formula in Excel to retrieve an array of data returned by your UDF code.

The biggest issue with taking this approach is that you need to know ahead of time the exact dimensions of the data being returned, which is not always the case (like the Query Table example below, or the consuming SharePoint Lists case).

The workaround to this is to use the idea of "paging" through your data if the data is likely to grow beyond the dimension of your Array Formula.

To implement this you would modify the existing UDF code to return only a preset number of Rows (say 100 rows) at a time.  Then you could create an Array Formula of 100 rows height and always have all of the data fit in it. When you need data past the first 100 rows you can use another parameter into the UDF as the "page number".  For example, if you call the UDF with the page parameter as 1 you get rows 1-100, but when you call the UDF with page parameter 2 you get rows 101-200... and so on.

You could use the same analogy in the Columns case as well if your data can grow width-wise.

By parameterizing the Page you can allow the end user to pick the page they are using through an Excel Services parameters, and thus allowing them to see all of the data n-rows at a time.

If you'd like to see some sample code for this send me an email, if I get enough requests I'll modify one of my solutions to include this workaround.

As you may or may not know by now, one of the limitations in this version of Excel Services is the inability to publish workbooks containing Query Tables (tables that have external data as their source).  There have been numerous blog posts on the web about how to covnert your QueryTable into a PivotTable to get this to work, unfortunately you loose some QueryTable functionality doing this, and you have to run some custom code against your workbooks (check out http://blogs.msdn.com/cumgranosalis for some add-ins that will do this for you).

I have been using a different workaround to achieve this same functionality, it's simple, works well with my UDF examples, and doesn't require any code (though you probably wouldn't want to convert large workbooks you have laying around by hand, but this may help with new ones).

 As I mentioned in this post you can have your UDFs return an array to the Excel workbook by entering them as an array formula. Once the data is in the workbook you will notice that structure-wise it looks very much like a Query Table, though you cannot sort/filter on it, you also can't simply create a table containing that range as tables cannot be created against array formulas.

 WORKAROUND

The workaround is simple, instead of creating a table containing the array formula returned from the UDF, we will create a table on a separate sheet which references the array formula's cells individually.

I've attached a workbook that does this, but in order for you to see what I'm doing on Excel client I have used the "=ROW()*COLUMN()" formula instead of an UDF which would evaluate to #NAME? on the client until you registered the dll... etc...

 The workbook contains an array formula in Sheet1 range A1:D7 with the formula "=ROW()*COLUMN()" entered with CTRL+SHFT+ENTER.

In Sheet2 you have a table from A1:E8 (one extra row for the column titles, one extra column for indexes).  You will notice a special INDEX column to the right of the table, this is filled as 1, 2, 3,..., 6, 7 and corresponds to the row in Sheet1 where the data for the current row in the table is located.

 Every other cell in the table (minus the INDEX column) contains the following formula:

=INDIRECT("Sheet1!R" & Table1[[#This Row],[INDEX]] & "C" & COLUMN(), FALSE)

 Basically what this is doing is creating an absolute reference to the cell on Sheet1, and grabbing it's value. You would actually also be able to do this by filling your table with absolute references like =$A$1, =$A$2,... etc, but there is no way that I know off (and I asked around quite a bit) to be able to enter those references automatically in a large range short of writing some code which I want to avoid.

 Either way, you should now see the values from the array formula on Sheet1 in your table on Sheet2 (plus the INDEX column on the right which you can hide).

 You can now Sort, Filter, and do anything you can do on a good old Query Table. If instead of using the simple "=ROW()*COLUMN()" function you used a UDF that reads from a SQL database and returns an array (or you could also use my UDF to read from SharePoint Lists) then you end up with an almost fully functional table of the external data.

 THE CATCH

There is always a catch... the one that seems to be prevalent here is the fact that you need to define right off the bat what your data dimensions will be when you enter the array formula, so if somehow your data grows bigger than the size you allocated for the array formula the table will not automatically grow to that size.  The workaround here is to make sure your array formula is big enough for your data to grow (pad it with some extra rows) and filter out any blank rows on the table so they don't show up until they have data on them.

 See sample workbook attached!

 

More Posts Next page »
 
Page view tracker