Programming, technology, and CRM – from a Belgian programmer exiled to Missouri
  • rss
  • Home
  • Contact Me
  • Welcome

Compress database backups with Powershell

Nicolas Galler | January 18, 2010

Disk space may be cheap but it is still not free! And, while SQL Server 2008 supports online compression of backups, it is only available in the Enterprise edition. So I wrote a simple powershell script (more like a snippet) to compress any backup (.bak and .trn files) older than 2 days.


cd E:\MSSQL\BACKUP\SalesLogix
dir *.trn,*.bak | where { $_.CreationTime.CompareTo([DateTime]::Now.AddDays(-2)) -lt 0 } |% `
{ & 'C:\Program Files\7-Zip\7z.exe' a "$_.zip" $_; rm $_ }

Could replace “.zip” with “.7z” to do a 7-zip compression – it will take a bit less disk space but more cpu. Could also be tweaked a bit to support recursion.

I saved that to E:\MSSQL\Backup\ZipBackups.ps1 and created a schedule task to invoke “powershell E:\MSSQL\Backup\ZipBackups.ps1″. This requires the execution policy to be set on powershell, to allow unsigned local scripts:


set-executionpolicy RemoteSigned

I am still working on getting more familiar with powershell as it can be a nifty tool (and is becoming more and more standard on Windows servers as it is bundled with other packages)

Comments
No Comments »
Categories
Tricks
Comments rss Comments rss
Trackback Trackback

More random errors.

Nicolas Galler | January 13, 2010

A quick offering to the great Google god, in case you are running into the same issue:

  • “NullReferenceException” in the “ExtractValuesFromCell” method – this is caused by the “pseudo” cell added by the SlxGridView. To work around, turn off the “ExpandableRows” flag.
  • Blank page with a NullReferenceException in the LookupControl ClientConfiguration.From method: check the provider listed in connection.config. It needs to be spelled “SLXOLEDB”. If it is spelled out “SalesLogix OLEDB Connection Provider”, it will fail (not sure why but on 7.5.2 sometimes the connection is output in that format – I think, because I created the connection in AA, instead of logging into the Admin first)
  • Web client crashes when grid.Sort is called – do not call that method from the Sorting handler because it will cause infinite recursion (the Sorting handler can often be empty)
  • AA gives ArgumentNullException when Update Properties is clicked: this is an installation problem. Run a repair. In fact, if you get random errors from AA, and they are not specific to one project, running a repair should probably be the first corrective action.
Comments
No Comments »
Categories
Saleslogix
Comments rss Comments rss
Trackback Trackback

Using Direct SQL in Web Grids

Nicolas Galler | January 8, 2010

Another (thankfully smaller) post on the SalesLogix journal, detailing how to use straight SQL in a web grid. I use that a lot when I have a complex, read-only query (so much faster than cranking out the corresponding C# code to do it through the entity model), and I know a lot of SalesLogix dev are very familiar with SQL, so figured it would be useful.

The article is at Back to Basics – Using Direct SQL in Web Grids

Comments
No Comments »
Categories
Saleslogix
Comments rss Comments rss
Trackback Trackback

Step by Step Guide to Custom Form Development with Visual Studio

Nicolas Galler | December 15, 2009

I think I just made the longest post ever on the SalesLogix Journal. It is a fairly complete guide on how to get started writing custom smart parts for SalesLogix in Visual Studio. I think it is a bit scary to get started with those but it is a must to provide rich functionality (for better or worse – but I think it is a good thing that Sage is not trying to cram every possible functionality into the QuickForms – their job is not to create a Visual Studio replacement!!)

Anyway, I might start writing most of the SalesLogix content through that channel so this blog does not look so much like a SalesLogix reference guide :)

Comments
No Comments »
Categories
Uncategorized
Comments rss Comments rss
Trackback Trackback

How to refresh tabs, from the client side (SalesLogix 7.5.2)

Nicolas Galler | December 11, 2009

As part of the many performance enhancement brought by this latest service pack, tabs are no longer automatically refreshing when a dialog closes. I think we can all agree that the gained performance is worth it :) But this has a few consequences:

  • First of all, if you are using a quickform as an insert form, you are all good. Yes, this is one of these cases where using a quickform actually paid off! Congratulate yourself for the good choice.
  • If you are using a custom smart part processed on the server side, it is quite straightforward, but requires a manual addition of this little piece of code to your server side script (right before or after closing the dialog):

    PanelRefresh.RefreshTabWorkspace();
  • If you are using a client-side customization (and I do use those once in a while for interactive or time-consuming processes), it is only slightly more complex – you need to trigger a refresh from the client side. Assuming you are closing the dialog with this type of code:
    DialogWorkspace._dialog.close();

    In that case I had to use a slight subterfuge to get the panel to refresh correctly. I added a hidden (server-side) button on the page:

    <asp:Button runat="server" ID="btnProcessServer" CssClass="btnProcess_server" style="display: none" />

    And then in the code-behind:

    /// <summary>
    /// This is called by the Javascript when processing is complete.
    /// Close the dialog, and ensure tab is refreshed.
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    void btnProcessServer_Click(object sender, EventArgs e)
    {
        DialogService.CloseEventHappened(sender, e);
        PanelRefresh.RefreshTabWorkspace();
    }

    Finally I just had to replace my javascript with the following to cause a postback and have the dialog closed from the code-behind from the button:

    $(".btnProcess_Server").click();

    Note that I am using the CSS class instead of the id, as the id is going to be transformed a bit by ASP.NET. It’s a bit of a cheat. There might be a creative way to do it entirely from client side, using the window.TabControl object (a reference to the tab workspace), however experience taught me creatively discovering hidden Sage Javascript API is a good way to waste my afternoon (and also get my butt kicked during upgrades!)

Comments
No Comments »
Categories
Saleslogix
Comments rss Comments rss
Trackback Trackback

Automatically importing default SalesLogix namespaces for C# code snippets

Nicolas Galler | December 8, 2009

When working on web client forms you may have seen this error:


e:\inetpub\wwwroot\PhysicianLiaison\SlxClient\SmartParts\Contact\ContactDetails.ascx(678): error CS0246: The type or namespace name 'IContact' could not be found (are you missing a using directive or an assembly reference?)

For example this happens when you use an unqualified reference in a C# code snippet, such as:


var myContact = (IContact)BindingSource.Current

You can’t add a “using” statement so the work around is to qualify all references:


var myContact = (Sage.Entity.Interfaces.IContact)BindingSource.Current

To save on the typing, you can add a default import to your web.config file. Simply do a search for “<pages>” and add the following under that tag (or if you don’t see a <pages> tag at all, add it under <system.web>):


<namespaces>
<add namespace="Sage.Entity.Interfaces"/>
</namespaces>

Of course this can be used with your custom namespaces as well. If you are using extension methods to define business rules (as explained in Easy Business Rules with Extension Methods) it will let you use those too.

Comments
No Comments »
Categories
Saleslogix
Comments rss Comments rss
Trackback Trackback

Make sure you disable debugging in production!

Nicolas Galler | December 2, 2009

Here is a quickie… Several times I have made the mistake of shipping a web.config with debugging enabled (fortunately always caught it at the last minute so far). This has a horrible affect on performance because it prevents caching. It can also cause some serious memory issues under heavy load. So I made myself a big warning on the login page:

Big old warning

The code for it looks like this (in Login.aspx):

    </asp:Login>
    <asp:Label style="clear: both; display: block; width: 100%; text-align: center; color: red; font-size: 24pt" runat="server" id="lblDebugWarning"
                Text="Debugging Enabled in web.config - Set to False for Production" />
</asp:Content>

And under Page_Load, very simple:

    protected void Page_Load(object sender, EventArgs e)
    {
        lblDebugWarning.Visible = HttpContext.Current.IsDebuggingEnabled;
        System.Web.UI.WebControls.CheckBox rememberMe = (System.Web.UI.WebControls.CheckBox)slxLogin.Controls[0].FindControl("chkRememberMe");

By the way it slightly funks up the display for IE6 – but only when the label is actually displayed, so not a big deal.

Comments
No Comments »
Categories
Saleslogix
Comments rss Comments rss
Trackback Trackback

Why I switched to Linux for Saleslogix Development

Nicolas Galler | December 2, 2009

This seemed like a no-brainer. SalesLogix is a Windows application, all the development tools run exclusively on Windows, and even though it does support a Linux database server (with Oracle) the vast majority of our customers are even running their database server on Windows. Nevertheless, Windows as a developer’s desktop has some serious issues (even more so for SalesLogix-specific development) and after realizing that I was spending most of my time inside of virtual machines anyway to work around 64-bit and IIS7 issues (and to take a break from Vista’s constant security nags), I decided to run a little experiment to see exactly how usable (or not) using Linux as a desktop for development of a Windows-based program would be. I loaded a copy of Ubuntu Linux on my workstation and started experimenting – I used the Linux desktop for email, web and editing, and used VirtualBox images for SalesLogix development.

The results? Well, they are in the title of the post! I don’t know if the Linux desktop will be a permanent thing on my home computer but it is definitely a big benefit on my work machine. It turns out that:

  • Installation and updates is quite a lot easier thanks to the built-in package manager – no need to look for, install and keep up to date 2 dozens third party programs because everything is included
  • The desktop has a few neat features that make it a perfect work environment – virtual desktops is the big one for me, it basically emulates additional monitors. The mouse focus is also nicer (you can get those effects with 3rd party programs and tweaks on Windows but not as well integrated). All in all the desktop is a bit more comfortable to me – could be because I was already quite familiar with it though.
  • A lot of neat and actually useful toys that come with the box. For example, there is a widget to which you can paste images to send them directly to an image sharing site – it’s great for posting screenshots on the SLX forums. Or a sticky note app (there is one in Windows 7 too but it is not terribly useful for me as it can’t sync between computers). Again, because they come with the system I do not need to spend additional time looking for them and keeping them up to date.
  • 32bit vs 64bit issues are non-existent – no “WoW64″ here. Oh, the sweet relief. I believe it was all worth it just to get rid of that nightmare.
  • Git. Git is not that slow on Windows, in fact it is a lot faster than the alternatives. But the first few times I ran it on Linux it happened so fast I thought there was a bug and it was not picking up my changes. I am not exaggerating – a local git clone of a Saleslogix repo goes down from 30 to 2 seconds. The integration with the merge tools is also better (a lot better). So now when I need to do a big merge I bring the repo to my Linux filesystem, do the merge, and send it back. Words fail to express how much more pleasant this is.
  • Warm fuzzy feeling from using an open source OS? Maybe :)

Now to be fair not everything is rosy… First of all be prepared for a fairly steep learning curve if you have no experience with Unix at all. To make things worse there are usually 2 ways to do most things – the “intuitive” way, through the UI, which takes a lot of clicks and is not always terribly reliable (though usually about the same as what it would be on Windows), and the “easy (not)” way, through the command line, which is very fast but requires you to know what you are doing. Even so, some operations require a bit of Googling and gentle coaxing – for example installing and configuring the NVidia driver for multiple monitors was not quite a point-and-click operation. A lot of the desktop functions are not extremely stable or polished – for example, the file browser crashes on me every few days, the UI stutters a bit when doing a disk-intensive operation (though it has no problem coping with the memory pressure of having 6 VMs running at a time, unlike Windows), Adobe Flash applications don’t always work fine, and because some of the fonts available on Windows are not present some web pages display incorrectly. And external devices are usually not “officially” supported – I have had good luck so far (I am actually able to customize all of my keyboard buttons which is better than what I could do in Windows, and my older scanner which does not have a Vista driver works fine on Linux) but I am sure esoteric USB devices or certain graphic cards might cause some issues. Well, these are the reasons I am still not quite sure I will keep it as a desktop OS for my home computer.

More importantly for work and development, while the integration with the Windows file shares is good, it is not perfect – sometimes I have to copy a file to my system, edit it, then copy it back. And I do miss Outlook (not that it is a fantastic program in itself – but the level of integration with Exchange is great). If I was using the Outlook calendar a lot I might be very unhappy – as it is I manage fine from my Blackberry.

My conclusion is not to encourage anyone to switch to Linux. Rather, an invitation to keep your mind open, as the ideal solution may not always be the obvious one!

Linux Desktop

PS: I opened an alternate blog at Nico’s Linux with the Linux-specific stuff, since it is not directly related to CRM.

Comments
No Comments »
Categories
Experiments, Saleslogix
Comments rss Comments rss
Trackback Trackback

Useful web development tools

Nicolas Galler | October 25, 2009

What are the tools you use every day… or at least on a very regular basis for web development? I sat down and made a list… leaving out the obvious Visual Studio and the stuff that was more specific to .NET (Reflector, windbg etc):

  • IETester – great for testing display of different IE version without switching between 3 vms
  • jsmin to minimize / combine javascript
  • Firebug and/or IE8 developer tools… duh! Can’t get very far without one of those any more.
  • IE7 developer tools – they tend to crash a lot on SlxWeb so I only use them when I need to troubleshoot an IE7-specific problem
  • Sizer – very useful to see what the page looks like at various resolutions
  • Fiddler – to snoop http… very neat
  • Tamper Data – Firefox extension to troubleshoot HTTP headers etc, sometimes I use it instead of Fiddler, or when I am on Linux. Fiddler is a lot more user friendly but it does not let you edit the headers on the fly.
  • Wireshark – a TCP capture tool… for when Fiddler is not enough! Thankfully I don’t have to use that one very often.
  • ScreenRuler for Gnome: this is Linux-specific but I am sure Windows equivalents exist – it pops a virtual ruler on the screen. Very handy when trying to align controls

And a few others that are not strictly web tools, but still extremely useful in web development:

  • KDiff3 – a diff tool. There are a number of other diff tools. WinMerge is a bit easier to use but I had trouble with some files with it (something to do with the newline styles, I think).
  • Notepad2 – a notepad replacement with syntax highlighting and other features. I use it a lot to peek at source files because it loads about 1000 times faster than Visual Studio (and even a lot faster than Vim)
  • Source control is a must: I use Git (actually msysgit, for Windows) for SlxWeb development and Subversion for most other projects. Subversion is a lot easier to use but does not work well for SlxWeb.
  • VirtualBox – I tried VMWare and VirtualPC as well, but the free versions of VMWare are very limited, and I found VirtualPC to have very poor performance.
Comments
2 Comments »
Categories
Programming
Comments rss Comments rss
Trackback Trackback

Simple Picklist – Enabling Picklist manager options for the web client

Nicolas Galler | October 5, 2009

One missing feature of the SLX web client some of our users have been very vocal about is the ability to manage picklist options (multi-select, alphabetical sort, etc) from the good old picklist manager.  What makes it even more confusing is that there is no indication in the picklist manager that the options are not actually going to take effect… but in fact in the web client these options are only taken from the picklist control itself (i.e., set via the App Architect or in the page’s code). 

Fortunately it is a reasonably simple problem to resolve since those picklist options are readily accessible from the database.  All we have to do really is wrap the creation of the picklist control with something that will know how to pull that info and set it on the control.  The simplest way to do that would probably be to subclass the control, but I decided to go with a decorator pattern instead (the idea was that this would let me change a bit more of the behavior, for example, replace the stock picklist with a regular dropdown).  So instead of using:

<SalesLogix:PickListControl runat="server" ID="pklType" PickListName="Account Type" AutoPostBack="true"  AlphaSort="true" MustExistInList="true" AllowMultiple="true"  />

I use:

<SSS:SimplePickList runat="server" ID="pklType" PickListName="Account Type" AutoPostBack="true"   />

Behind the scene the SimplePicklist controls reads the attributes from the database and create a Saleslogix picklist control with the proper settings, something like this:

_picklist = new PickListControl();
if ((_storageMode & PicklistStorageMode.Id) != 0)
    _picklist.StorageMode = Sage.Platform.Controls.StorageModeEnum.ID;
else if ((_storageMode & PicklistStorageMode.Code) != 0)
    _picklist.StorageMode = Sage.Platform.Controls.StorageModeEnum.Code;
_picklist.PickListName = _picklistName;
_picklist.AllowMultiples = _attr.AllowMultiples;
_picklist.AlphaSort = _attr.AlphaSorted;
_picklist.NoneEditable = _attr.NoneEditable;
_picklist.Required = _attr.Required;
_picklist.MustExistInList = _attr.ValueMustExist;
_picklist.PickListValueChanged += delegate
{
    if (TextChanged != null)
        TextChanged(this, EventArgs.Empty);
};
parentControl.Controls.Add(_picklist);

This works fine for custom smart parts, how about for QuickForms?  Well, it is possible to change the template there too, but as it is global (will affect nearly every picklist in the client) it is a bit scarier :)

In the Model\QuickForms\Web\QFSLXPickList.WebControlRenderingTemplate.vm I changed the control to use my “SimplePickList” instead of a PickListControl

## Simple Picklist alternative (to automatically determine the sort etc)
    <SSS:SimplePickList Compatible="true" runat="server" ID="${qfcontrol.ControlId}" #if($qfcontrol.IsReadOnly)ReadOnly="true" #end
#if(!$qfcontrol.Enabled)Enabled="false" #end
#if($qfcontrol.ToolTip != "") ToolTip="<%$ resources: ${qfcontrol.ControlId}.ToolTip %>" #end
#if($qfcontrol.HotKey != "")AccessKey="$qfcontrol.HotKey" #end
#if($qfcontrol.PickListName != "")PickListName="$qfcontrol.PickListName" #end
#if($qfcontrol.HasActionCode || $qfcontrol.AutoPostBack)AutoPostBack="true" #end
#if($qfcontrol.Required)Required="true" #end
#if($qfcontrol.MaxLength > 0)MaxLength="$qfcontrol.MaxLength" #end
#if($qfcontrol.TabIndex > 0)TabIndex="$qfcontrol.TabIndex" #end
#if($qfcontrol.StorageMode != "Text")StorageMode="$qfcontrol.StorageMode" #end
#if($qfcontrol.StyleScheme != "")CssClass="$qfcontrol.StyleScheme" #end
#if(!$qfcontrol.Visible)Visible="false" #end  />

The “Compatible=true” setting is something I added to avoid bad surprises – it forces the list to display as a standard Saleslogix picklist, instead of e.g. a dropdown.

Now because it is a custom control, it requires a change to web.config too, something like this (under system.web/pages/controls):

<add tagPrefix="SSS" namespace="SSSWorld.Slx75.Web.Controls" assembly="SSSWorld.Slx75"/>

I think it works great, but haven’t tried on a production system yet – I am going to save it for a next big project when I can get a resource to QA the entire app!  I do already use the “small” version in production in my custom smart parts, though.  I saved the code under here, if interested feel free to rip it up (though it probably has some extra dependencies so it will require a bit of cleanup).

So although I think the PickListControl should support this out of the box it is nice to see that it is not too hard to add the functionality ourselves.

Comments
1 Comment »
Categories
Uncategorized
Comments rss Comments rss
Trackback Trackback

« Previous Entries

Categories

  • Experiments (4)
  • Interesting (1)
  • MSCRM (1)
  • Programming (60)
  • Rant (3)
  • Saleslogix (34)
  • Tricks (8)
  • Uncategorized (23)

Post History

  • 2010
    • January (3)
  • 2009
    • March (2)
    • April (1)
    • May (3)
    • June (3)
    • July (1)
    • September (3)
    • October (2)
    • December (5)
  • 2008
    • January (9)
    • February (4)
    • March (9)
    • April (1)
    • May (5)
    • June (8)
    • July (1)
    • August (2)
    • September (1)
    • November (1)
    • December (3)
  • 2007
    • January (3)
    • February (7)
    • March (1)
    • April (3)
    • May (6)
    • June (2)
    • July (1)
    • August (2)
    • September (5)
    • October (3)
    • November (5)
    • December (4)
  • 2006
    • January (2)
    • September (1)
    • November (3)
    • December (4)
  • 2005
    • April (1)

Meta

  • Log in
  • Entries RSS
  • Comments RSS
  • WordPress.org
rss Comments rss valid xhtml 1.1 design by jide powered by Wordpress get firefox