Wednesday, August 20, 2008

Business Objects XI R2 Search Web Part Sharepoint Part II

Like i promisse, have the webpart for sharepoint for Business Objects search, but i use the Business Objects web services consumer common classes.

You will need to convert the Business object Web Services in Class
To do That you will need to follow this steps:
Path "C:\Programas\Microsoft Visual Studio 8\SDK\v2.0\Bin"
wsdl.exe /l:CS /n:BusinessObjects.DSWS.Session /out:Session.cs http://[CMS_SERVER]:8080/dswsbobje/services/session?WSDL
wsdl.exe /l:CS /n:BusinessObjects.DSWS.BICatalog /out:BICatalog.cs http://[CMS_SERVER]:8080/dswsbobje/services/bicatalog?WSDL
wsdl.exe /l:CS /n:BusinessObjects.DSWS.ReportEngine /out:ReportEngine.cs http://[CMS_SERVER]:8080/dswsbobje/services/reportengine?WSDL

using BusinessObjects.DSWS.Session;
using BusinessObjects.DSWS.BICatalog;
using BusinessObjects.DSWS.ReportEngine;

or download .NET Consumer Library

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Web.UI;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.ComponentModel;
using System.Xml.Serialization;
using Microsoft.SharePoint.WebPartPages;
using System.Net;
using BusinessObjects.DSWS.Session;
using BusinessObjects.DSWS.BICatalog;
using BusinessObjects.DSWS.ReportEngine;

namespace SearchBOXI
[ToolboxData("<{0}:SearchBO runat=\"server\" />")]
public class SearchBOXI : Microsoft.SharePoint.WebPartPages.WebPart
#region Variables
string html;
private string _BOServer = "http://localhost:8080";
private string _Password;
private string _Login;
private string _Domain;
private string _URLSession = "http://localhost:8080/dswsbobje/services/session";
private Button BtSearch;
private Label LbSearch;
private TextBox TxtSearch;
protected Auth _Auth;
private String link;
public enum Auth
secEnterprise, secLDAP, secWinAD
public SearchBOXI()
this.ExportMode = WebPartExportMode.All;
#region Public Personalizable Properties
[WebDescription("Business Objects Server Name")]
[Category("Business Objects Option")]
[WebDisplayName("Business Objects Server Name")]
public string BOServer
return _BOServer;
set { _BOServer = value; }
[WebDescription("URL Web Service Session")]
[Category("Business Objects Option")]
[WebDisplayName("URL Web Service Session")]
public string URLSession
get { return _URLSession; }
set { _URLSession = value; }
[Category("Business Objects Authentication")]
public string Login
get { return _Login; }
set { _Login = value; }
[Category("Business Objects Authentication")]
public string Password
get { return _Password; }
set { _Password = value; }
[Category("Business Objects Authentication")]
public string Domain
get { return _Domain; }
set { _Domain = value; }
[Category("Business Objects Authentication")]
public Auth Author
get { return _Auth; }
set { _Auth = value; }
#region Create Child Control
protected override void CreateChildControls()
this.BtSearch = new Button();
this.BtSearch.ID = "_BtSearch";
this.BtSearch.Text = "Search";
this.BtSearch.Click += new EventHandler(BtSearch_Click);
this.LbSearch = new Label();
this.LbSearch.ID = "_LbSearch";
this.LbSearch.Text = "Document Search BO";
this.TxtSearch = new TextBox();
this.TxtSearch.Width = Unit.Pixel(250);
this.TxtSearch.ID = "_TxtSearch";
void BtSearch_Click(object sender, EventArgs e)
private void Search()
BusinessObjects.DSWS.Connection boConnection = null;
string boConString = URLSession;
boConnection = new BusinessObjects.DSWS.Connection(boConString);
boConnection.Credentials = CredentialCache.DefaultCredentials;
//boConnection.Credentials = new NetworkCredential(Login, Password, Domain);
boConnection.IsKerberosAuthenticationEnabled = true;
EnterpriseCredential boCredential = new EnterpriseCredential();

if (Domain.Trim().Equals(""))
{ boCredential.Domain = string.Empty; }
else { boCredential.Domain = Domain; }

if (Login.Trim().Equals(""))
{ boCredential.Login = string.Empty; }
else { boCredential.Login = Login; }

if (Password.Trim().Equals(""))
{ boCredential.Password = String.Empty; }
{ boCredential.Password = Password; }

if (Auth.secEnterprise == Author)
{ boCredential.AuthType = "secEnterprise"; }
else if (Auth.secLDAP == Author)
{ boCredential.AuthType = "secLDAP"; }
else if (Auth.secWinAD == Author)
{ boCredential.AuthType = "secWinAD"; }

Credential val = new Credential();
Session boSession = new Session(boConnection);
SessionInfo boSI = boSession.Login(boCredential);
string Token = boSI.DefaultToken;
String[] strBOCatURL = boSession.GetAssociatedServicesURL("BICatalog");
BICatalog boCatalog = BICatalog.GetInstance(boSession, strBOCatURL[0]);
ReportEngine oDSWRE = new ReportEngine(boCatalog.Connection, boSession.ConnectionState);
BusinessObjects.DSWS.BICatalog.SortType[] mySort = new BusinessObjects.DSWS.BICatalog.SortType[1];
mySort[0] = BusinessObjects.DSWS.BICatalog.SortType.NAMEASC;
SimpleSearch mySearch = new SimpleSearch();
mySearch.InAuthor = Login;
mySearch.InName = this.TxtSearch.Text.Trim();
mySearch.ObjectType = "documents";
link = "";
BICatalogObject[] searchResults = boCatalog.Search(mySearch, mySort, null, null, InstanceRetrievalType.ALL);
foreach (BICatalogObject myBOCatObject in searchResults)
link = BOServer + "/businessobjects/enterprise115/desktoplaunch/InfoView/CrystalEnterprise_Webi/" + myBOCatObject.UID + "&logonToken=" + Token;
html = link;


catch (Exception ex)
html = "No values...
" + ex.Message;
protected override void Render(HtmlTextWriter writer)
catch (Exception ex)
writer.Write(ex.Message + " " + ex.StackTrace);

Friday, August 15, 2008

Business Objects XI R2 Search Web Part Sharepoint

Hi, i am preparing a Business Object search Web part using Sharepoint,
Will try use a litle of Business Object SDK and Sharepoint SDK.

In 1 or 2 days will make a Beta launch on codeplex.

Stay tune...

Wednesday, August 13, 2008

How to get user Token Business Object XI R2


Working with Business Object Framewok can be tricky, but when you are working and need to make link to BO, without pass the authentication page on BO, this litle example can help get the token to create directs link to Web Inteligence.

using CrystalDecisions.Enterprise;

String Token;
using (CrystalDecisions.Enterprise.SessionMgr sessionMgr = new CrystalDecisions.Enterprise.SessionMgr())
EnterpriseSession enterpriseSession = sessionMgr.Logon("Login", "Password", "BOServer", "secEnterprise");

Token = enterpriseSession.LogonTokenMgr.CreateLogonTokenEx("", 60, 100);


Tuesday, August 12, 2008

Integrating Microsoft CRM 4.0 with Windows SharePoint Services

If you are a Developer, configuration and implementation etc etc of Sharepoint and Microsoft CRM, this is a book that helps you create a real integration, dashboards, data, etc etc.
Great Book.

Integrating Microsoft CRM 4.0 with Windows SharePoint Services

Here a excelent article Link about Sharepoint and CRM
"Developing a SharePoint custom field type for displaying CRM 4.0 data"

Display a SharePoint document library in a Microsoft Dynamics CRM 3.0 form

SharePoint Document Libraries in Microsoft CRM

Creating a Custom Web Service in SharePoint for Uploading Document
"upload the document to SharePoint document library whenever a file has been attached to our entities in Microsoft Dynamics CRM"

Use case: Integrating Microsoft Office SharePoint with Microsoft Dynamics CRM

Wednesday, August 06, 2008

Business Objects Dashboard Sharepoint MOSS2007 Solution Architecture

Business object is a very powerfull Tool in BI World and Web Inteligence Reports are so great to users because can make their own reports, but to intregrate Dashboard with Sharepoint the Permorfance can be slow when opens a report?

This Architecture try to have a better performance on reports.

Have Business Objects in one side and Microsoft Sharepoint 2007 in the other.

Need to create Dashboards on Sharepoint from Business Object reports (Web Inteligence ) but if i use Business Object Web Part, is a excellent BI Tools but need to aware of a lot of possible issues like Authentication, performance(Loading Reports with huge amount of data can take some time) ...

If you need real time Data, you will need to use Busines Object Web Part or you can make code to call the reports in your SharePoint environment.
Here some articles:
Business Objects XI R2 List Treeview Reports With SharePoint
Business Objects XI R2 Search Web Part Sharepoint Part II
How to get user Token Business Object XI R2
"Single Sign-On and Active Directory-SSO with Integration Option for Microsoft SharePoint XI 3.1"

If you need to show temporary reports like "Performance of the day" or other time define Reports and Dashboard you can create or solution like this:

So need to improve performance page loading on Sharepoint Dashboard, html page can be a solution.
I reach this Solution (I dont say it the best, If you have one better, you can help build...).
Schedule every day the web Inteligence report to a Html page and Show in Sharepoint by Dashboard.

1º Step, Business Objects Reports
Schedule BO to send every day a Email with report with excel file,
"Dont now how to send Html file..." :(
You can send to a phisical folder, (Local Folder Server or FTP)

2º Step, Incoming mail will redirect to Document Library (If you chose Email)
There Document Library will start Event Handler to convert XlS file to Html

3º Step, Create 2 Webpart.
First will list Report Files.
Secont will show Report in HTML.
Create a connection betwen Librarys.
Loading Reports will be fast.

I jump many and many adminstrations steps, "exchange folder, acounts, etc" but just want to show a global idea.
Ok now is done,
Permission problems?
Can use the sharepoint Permission to control Access.

I also recomend install "Business Object XI Release 2 SharePoint 2007 Integration Kit" WebParts are very usefull, but have some limitation like only work with 32 Bit...

Hope this article help you.

SharePoint STSADM Commands


How many of you have problem With Stsadm, ALL.
Every time i work with Sharepoint have to learn a new command, STSADM is real techincal stuff, backup, restore, attach database, stop search, crawl, you say and its there...

Microsoft have launch a technical manual that explains the stsadm command
Office SharePoint Server IT Pro content CHM

Here you have a good site that explains the using of STSADM command with excelent

Sharepoint Menu Document Library Links

You may ask to your self, How do i get the Links to delete a list item?
Microsoft have a litle tutorial Using the URL Protocol that help you building you url and add the parameters to create a new List, or delete a ListItem like this example

Delete Listitem:

New List:

This values are direct, you problaby ask "how do i get dinamyc, directly from the Table", and i say yes is possible..., how?
Go to Core.js, this file is located:
C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS\1033

This file in javascript is very important because already have a lot of method that return list name, id...

function Custom_AddDocLibMenuItems(m, ctx) ="Function to add Custom Menu"
ctx.HttpRoot = "Url Root";
currentItemID ="ItemID";
ctx.listName ="ListID";
ctx.imagesPath="Path for images" ctx.imagesPath + 'Folder.GIF'
GetAttributeFromItemTable(itemTable, 'Url', 'ServerUrl')=Get File Path
CAMOpt(m,"Description",ActionOnClick,ImagePath)=Add Function to menu
CAMSep(m) ="Create a Separator on Menu"
return(true)= Default menu is off
return(false)= Default menu is on

This file help me creating my sharepoint upload Document webpart.

Tuesday, August 05, 2008

Hide Sharepoint List Sharepoint Designer, SDK

Updated article with SharePoint 2010 Here

Today i want to show how to hide a Sharepoint List from users and administrators.
There are 2 way to hide Sharepoint List via Browser
By code or by Sharepoint Designer.

On Sharepoint Designer,
Open Web site, select you List and select check box "Hide".

On Sharepoint SDK
SPWeb Web = SPContext.Current.Web;
SPList List = Web.Lists["Your_List_Name"];
List.Hidden = true;

Hope you like.

Add Account Company logo on Microsoft CRM 3.0

Normaly Company want to know the logo of the Account, want to feel close to final client, by default Microsoft CRM dont give you a field to add a photo of your Account or contact.
So i make this litle code, using external tool like Access, page of, and configuring a iframe.
This trick save me a lot of times.

Create a new Database Where i collect information on Access.

Create a new Table add the following columns
Id=Guid of Account (Text)
Foto=Binary of the Photo(The image will be save on you Access file)

2º Step
On Microsoft CRM Configuration, select Account, and Form.
There create a Iframe please select the option to object code to the url, like "ID={Guid}"
(you Put)Iframe=/photo/photo.aspx
When navigatin the result will be something like this
This is very usefull, explore and you will like the final result.
After This, publish you configurations.

3º Step
Ok now we can start with code

Let start with Page life Cycle

BtDel.Attributes.Add("onclick", "javascript:if(confirm('Delete Photo?')== false) return false;");
MemoryStream stream = new MemoryStream();
OleDbConnection connection = new OleDbConnection(@"Provider=Microsoft.Jet.OLEDB.4.0;Persist Security Info=False;data source=" + Server.MapPath("Foto.mdb"));
OleDbCommand command = new OleDbCommand("select Foto from Foto where ID="+ Request.Params["id"].ToString(), connection);
byte[] image = (byte[])command.ExecuteScalar();
if (image != null)
Upload.Visible = false;
BtAdd.Visible = false;
BtDel.Visible = true;
stream.Write(image, 0, image.Length);
DynamicImage1.ImageBytes = stream.ToArray();
DynamicImage1.ImageFile = "http://[server]/_imgs/grid_Temp.gif";

catch( NullReferenceException ex )
DynamicImage1.ImageFile = "http://[Server]/_imgs/grid_Temp.gif";
Upload.Visible = false;
BtAdd.Visible = false;
BtDel.Visible = false;
Console.WriteLine( "Caught error: {0}.", e);


Now Event Handler to add Photo

int len = Upload.PostedFile.ContentLength;
byte[] pic = new byte[len];
Upload.PostedFile.InputStream.Read(pic, 0, len);
// Insert the image and comment into the database
OleDbConnection connection = new OleDbConnection(@"Provider=Microsoft.Jet.OLEDB.4.0;Persist Security Info=False;data source=" + Server.MapPath("Foto.mdb"));
OleDbCommand cmd = new OleDbCommand("insert into Foto "
+ "(ID, foto) values (" + Request.Params["id"].ToString() +",@pic)", connection);
cmd.Parameters.Add("@Pic", System.Data.OleDb.OleDbType.Binary,pic.Length).Value = pic;
Page.Response.Redirect(Page.Request.Url.ToString(), true);


Now Event Handler to Delete Photo

OleDbConnection connection = new OleDbConnection(@"Provider=Microsoft.Jet.OLEDB.4.0;Persist Security Info=False;data source=" + Server.MapPath("Foto.mdb"));
OleDbCommand cmd = new OleDbCommand("Delete from foto where ID=" + Request.Params["id"].ToString(), connection);
Page.Response.Redirect(Page.Request.Url.ToString(), true);

Ok The essencial is here,
Hope you like this article, works for me.

Problems accessing Sharepoint or Microsoft CRM, "Host" file

You problably have this problem, "or not", but is normal having problem accessing Sharepoint and Microsoft CRM, you have all configurations right on server and allways works fine there, some computers can access sharepoint or Microsoft CRM, other dont, but you say to youself "There all the same, whats wrong", well sometimes litle things can be like a mosquito.

This problem can be a simple thing like Changing and adding line on "Host" File.
This file is located on your PC "C:\WINDOWS\system32\drivers\etc" if you have Windows XP.

Have to open "Host" file and add a mapped address adding IP and server name
example: crm:5555

Try again and you problaby will get access.
Remember this could be only one of the problem, "proxys", network problem, DHCP, there other issues, but now only focus this.

Hope this article help.

Monday, August 04, 2008

Control your Sharepoint Permissions in SDK

One big problem in sharepoint is permission, allways permission, today have contribute, tomorow have read.
This is not the best policy, allways changing...., have to make rules! Talk to you client, sit 2,3,4,6 hours, 2 day... trying to understand the business, what can they see, get and put Data, Forms to be made, who are the final users, Designer... "My Kingdom" for a good designer, SharePoint could do nothing but if you have a good designer people will have apetite to prove sharepoint :).
Define all, only there you can start managing "if is a customer pre-requisite" permission.

Hope you like, and "CODE WILL THE LAST THING YOU TOUCH, ALLWAYS", not because is hard "not...", but can compromise times of develomp, and business, use other tools like Sharepoint Designer and Third tool exist in "Codeplex" and other Sites to help Configuring your site.

Here you have a litle code to add, remove group and change permissions:
Managing Permission in a ListItem
//add user
SPListItem i = fileI.Item;
i.Web.AllowUnsafeUpdates = true;
i.Web.AllowUnsafeUpdates = true;
SPRoleDefinition rd = i.Web.RoleDefinitions.GetByType(SPRoleType.Reader);
SPRoleAssignment ra = new SPRoleAssignment(SPUser user);

//Change Permission Groups To read
SPListItem itemH = file.Item;
SPRoleDefinition rd = itemH.Web.RoleDefinitions.GetByType(SPRoleType.Reader);
SPRoleAssignment ra;
foreach (SPGroup Group in cweb.Groups)
ra = new SPRoleAssignment(Group);

//Remove a Group
SPGroup group = cweb.Groups["Group Name"];

Update ListItem Sharepoint programmatically


How many time you try update a listitem and give a error like "Access Denied" or "Error Page", when you are working with event handlers or a simple postback, well the trick is using "AllowUnsafeUpdates"

SPSite site = SPControl.GetContextSite(Context);
SPWeb web = site.OpenWeb();

SPSite csite = new SPSite(site.ID);
SPWeb cweb = csite.OpenWeb(web.ID);
csite.AllowUnsafeUpdates = true;
cweb.AllowUnsafeUpdates = true;
SPFile file = cweb.GetFile(this.fileURL.Value);
SPListItem itemH = file.Item;
itemH.Web.AllowUnsafeUpdates = true;
itemH.Web.AllowUnsafeUpdates = true;
itemH["Title"] = "My Name";


Sunday, August 03, 2008

Auto Populate Follow Up "Phone Call" CRM


This tip is for free, :)

How many times you think, "finish phone call and need to make a follow up and want to populate with data", well computer dont think for us, but we can create some rules.
This rules can be done with litle code, just use this litle javascript "On_load" event "Phone call Form" to create a fast follow up.
This litle code, help me a lot with Lazy customers :)
Hope you like this article.

I use Portuguese CRM, please change some Var to use with English
//Follow Up
document.getElementById("ContextSelect").onblur = ChangeSeguimento;

function OpenFollowUp()

function ChangeSeguimento()
if(document.getElementById("ContextSelect").DataValue == "followup")
//English use "Activity Type"
//Portuguese use "Tipo de Actividade"
if(document.getElementById("activitytype").innerText == "Activity Type")
document.getElementById("activitytype").id = "activitytype1";
document.getElementById("activitytype").onblur= PreencheType;


function PreencheType()
if(document.getElementById("activitytype").DataValue == "4210")
var lookupItem = new Array;
lookupItem = document.getElementById("from").DataValue;

var lookupItemTo = new Array;
lookupItemTo = document.getElementById("to").DataValue;

document.getElementById("from").id = "from1";
var lookItmGrp = new Array();
lookItmGrp[0] = new LookupControlItem(lookupItem[0].id , lookupItem[0].type,lookupItem[0].name );
document.getElementById("from").DataValue = lookItmGrp;
document.getElementById("from1").id = "from";

document.getElementById("to").id = "to1";
var lookItmGrp1 = new Array();
lookItmGrp1[0] = new LookupControlItem(lookupItemTo[0].id , lookupItemTo[0].type,lookupItemTo[0].name );
document.getElementById("to").DataValue = lookItmGrp1;
document.getElementById("to1").id = "to";
//document.getElementById("activitytype1").id = "activitytype";

Friday, August 01, 2008

Calculator Sharepoint Web Part

Hi again,

Here you have a nice calculator inside Sharepoint, cool stuff :)
Import File .dwp and drag to web part zone.

Hope you like and help...

Can download or
Download Calculator.dwp

Connect Sharepoint User Info Web Services


This arthicle will try to help you to make a simple connection via Web services and Sharepoint Designer to Users Info .

First you will need to create Datasource Library, go to the tab "Data Source Library" and select option "XML Web Services".

There you create a new connection.
First: you need to now what Web Service you need.
Physical the Web services are located here:
:\Program Files\Common Files\Microsoft Shared\web server extensions\12\ISAPI

To the purpose whe want you can use the "/_vti_bin/lists.asmx"

Second: Select the operation "GetListItems"

Third: Now you have a list of Parameters
Need to fill Parameter "listname" with name "User Information List"

After that you have connect to Web Service.
Then you need to work with Data.
Select the create Web Service on Datasource Library, and select "SHOW DATA".
There you select the field you want to show and when select "Multiple View", and the data will be show in a Table.

You are also able to use user information calling the Listname UserInfo, This happen if  you multiple language like German, the "User Information List" will have different name for that and UserInfo will be generics.

<soapenv:Envelope xmlns:soapenv=''> \
  <soapenv:Body> \
   <GetListItems xmlns=''> \
      <listName>UserInfo</listName> \
    </GetListItems> \
 </soapenv:Body> \

Lists.GetListItems Method

Hope this litle arthicle help.