Studying My Masters Through Charles Sturt University

In March I started studying, via distance education, a Graduate Certificate of Systems Development with Charles Sturt University. The Graduate Certificate is made up of 4 units which can count towards the full Masters course (which I plan on continuing with - I figured it would be safer to aim for something achievable first, and seeing if I still liked studying enough to commit a few years to it!)

Charles Sturt University has a great reputation for its distance education, but the reason I signed up was that it works hand-in-hand with industry so you achieve the Masters and industry certification (in my case, project management).

Study is waaaay different than it was when I was a full-time Uni student last century. My situation has changed too in that now I have a full-time job, a wife and three kids, and a lot more commitments. As I'm doing distance education, there's no "class" time and studying is largely self-directed. Forums are provided and some subjects have weekly webcasts (Marco's webcasts particularly were entertaining and informative) but it can feel a little "here's the books and study notes, here's your assignments, we'll see you later" which can be initially daunting.

I hope to blog more of my experiences - including my first two subjects, and why I'm studying project management - over the next couple of weeks.

Tags: , , ,

Saving Windows XP "My Network Places" to a Text File

I like the "My Network Places" functionality in Windows XP. The way I use Windows Explorer is to have mapped drives for high-use locations. "My Network Places" becomes a psuedo-"favourites" - linking to, for example, a folder where a third-party extract is dropped, or a shared folder from another department, or a folder used for backups but rarely accessed.

With that in mind I thought it would be handy to keep a copy of the UNC paths contained in "Network Places". There's a few tools that will allow you to print folder contents ("Network Places" is stored in the "NetHood" folder in your user profile) but that only resulted in the names, not the UNC paths.

Here's the VBScript I ended up cobbling together to save "My Network Places" to a text file, enumerating each item and getting the name as well as the UNC path. I hope this helps if, like me, you've ever considered just taking a screenshot of Windows Explorer to keep track of your network places:

Special Note: This works perfectly on my PC, however I can't take any responsibility for it working anywhere else. It's just a quick script that did the job for me, not a fully debugged application.

' ------------------------------------------------------------------------------
' Writes all folders/links in "My Network Places" on Windows XP to a text file
' Thomas Williams 13-May-2010

' adapted from http://www.tek-tips.com/viewthread.cfm?qid=1309939&page=9 and
' http://blogs.technet.com/heyscriptingguy/archive/2005/05/09/how-can-i-create-a-shortcut-in-my-network-places.aspx and
' http://msdn.microsoft.com/en-us/library/bb774004%28v=VS.85%29.aspx
' ------------------------------------------------------------------------------

Const NETHOOD = &H13&

Set objShell = CreateObject("Shell.Application")
Set objFSO = CreateObject("Scripting.FileSystemObject")

' file to write to (overwrite without prompting)
Set outputFile = objFSO.CreateTextFile("C:\Network Places List.txt", True)

' get the NetHood folder on Windows XP for the current logged in user
Set objFolder = objShell.Namespace(NETHOOD)

' loop through all items in NetHood folder
For Each objItem in objFolder.Items
    ' if the item is a link e.g. not "Entire Network"
   If objItem.IsLink Then
        ' get the link/shortcut for the item
       Set objLink = objItem.GetLink
        ' write to the output file, the display name of the folder, and the UNC path
       outputFile.WriteLine(objItem.Name & vbTab & objLink.Path)
    End If
   
Next

' close the output file
outputFile.Close

The tricky part was dealing with the list of items returned by Shell.Namespace and finding out how to get the link properties from a FolderItem...luckily I'm on first-name speaking terms with my friend the MSDN Library :-)

Tags: ,

My Firefox Tab Scope Add-On Wish List

Tab Scope is a very handy Firefox add-on that shows a pop-up preview of a tab's contents when hovering over a non-selected tab...oh, a picture probably will say it better:

The developers have clearly put a huge amount of work into Tab Scope over the years and have largely got it right, and in addition to a preview image, there's a couple of controls like back, forward, refresh in the pop-up itself. After using Tab Scope version 0.3 with the fx4 theme for a couple of weeks, there's a few things on my wish list, however:

Left-clicking on the actual preview image does nothing: it should at least act like a left-click on the tab, and switch to the tab. Wish 1: Left-clicking on a preview image should switch to the tab.

When zooming, left-clicking on a link or button in the preview image opens the link: a nice touch...that I discovered entirely by accident. I feel that the negative (e.g. hit-and-miss clicking on microscopic text) outweighs the positive (e.g. navigation from within a preview window). Wish 2: In line with wish 1 above, left-clicking on a zoomed preview image should also switch to the tab.

When zooming, there's no horizontal scroll: the zoom is not particularly useful on wide, centred designs:

Wish 3: An alternative might be to zoom the entire page, like a bigger version of the non-zoomed image preview (you'd lose the ability to click on links).

Wish 4: OK, I'm into overtime here because in most stories you're only granted 3 wishes. I'd love to see Tab Scope work with the Smart Stop/Reload add-on, which shows the stop button when the page is still loading, and the reload button when the page has finished.

When zooming, the vertical scroll is not easily discoverable: you can see from the zoomed image above that there's no scrollbars, but if you scroll the mouse wheel when hovering over the preview, the preview will scroll vertically. This is another feature I found by accident. Wish 5: make scrolling more discoverable (hmmm, I'll leave the implementation to someone with more imagination than me).

Wish 6: The close button should probably be in the top-right corner of the pop-up, which matches where the close button would normally be on the tab. This may not suit everyone's themes, though. You could go even further and specify that the back and forward buttons on the pop-up preview were styled like your theme's styles, but I think that's probably asking a bit much :-)

Wish 7: My last wish is purely aesthetic - make the pop-up preview joined to the tab somehow. In the zooomed preview image above, it looks like the pop-up is joined to the second, active tab ("Google"), instead of the first tab ("Tab Scope").

OK, I'm done. What do you think? Would you use Tab Scope, and given more wishes than Aladdin, what would you improve?

Tags: , ,

SQL Error: Cannot resolve collation conflict for DISTINCT operation

I'd never run into this one before and am not likely to again, but the fix is pretty simple and worth posting for my own reference (and I hope it helps anyone googling for it too).

The problem occurs in SQL Server 2005 or SQL Server 2008 when you try and select a DISTINCT range of values from a sub-query that uses a UNION or UNION ALL to union two columns with different collations. The problem may occur if the collations are set differently at a database level while unioning two tables from different databases, and also at the column level within the same database. As with other "Cannot resolve collation conflict for XXX operation" errors, the fix is the same - convert the offending columns to the same collation using COLLATE DATABASE_DEFAULT:

--Step 1: create two similar tables with columns with different collations
DECLARE @temp1 TABLE (
    [Test1] NVARCHAR(100) COLLATE SQL_Latin1_General_Cp1250_CS_AS
)
DECLARE @temp2 TABLE (
    [Test2] NVARCHAR(100) COLLATE Icelandic_CS_AS
)

--Step 2: put in some values
INSERT INTO @temp1 VALUES(N'Falcon')
INSERT INTO @temp1 VALUES(N'Eagle')
INSERT INTO @temp1 VALUES(N'Tomcat')

INSERT INTO @temp2 VALUES(N'Mirage')
INSERT INTO @temp2 VALUES(N'Viggen')
INSERT INTO @temp2 VALUES(N'Harrier')

--Step 3: THIS WILL CAUSE A "Cannot resolve collation conflict for DISTINCT operation" ERROR
--Comment the following out to run step 4
--get distinct values from both tables, joined using UNION ALL in a subquery
SELECT DISTINCT [Test]
FROM (
      SELECT [Test] = [Test1] FROM @temp1
      UNION ALL
      SELECT [Test2] FROM @temp2
     ) I

--Step 4: the fix is to convert the columns to same collation using COLLATE DATABASE_DEFAULT
SELECT DISTINCT [Test]
FROM (
      SELECT [Test] = [Test1] COLLATE DATABASE_DEFAULT FROM @temp1
      UNION ALL
      SELECT [Test2] COLLATE DATABASE_DEFAULT FROM @temp2
     ) I
 

Tags: , ,

Google Reader's "Explore" feature

I recently discovered the new Google Reader "Explore" section, just above my subscriptions in the left-hand panel:

Using it like my screenshot above - not expanded - means that when I click on the "Explore" text, I get an endless, combined feed of everything Google Reader thinks I might like (there's actually been some good stuff there too) for the price of one line of text.

This is much handier than viewing a list of feed titles using the old "Browse for stuff" link and having to make a decision to even click on a feed based on the title, author and number of subscribers.

Well done Google for a smart, non-obtrusive way to help users find more reading.

Tags: , ,

Blockbuster Signup WTF

I love the DailyWTF blog and recently had a WTF moment of my own while signing up at the Blockbuster (Australia) website:

 

In my case the password wasn't long enough, but Blockbuster effectively "threw the book" at me and dumped all the password error text onto the screen.

I read and re-read the highlighted text but it still didn't make sense, especially considering I didn't use any non-alphanumeric characters. If something should "contain at least zero" then it could also be written "should not contain" which might have come off better.

Tags: , , , ,

The Case For Renaming Controls In a Reporting Services Report

Since my Access days, I've believed in renaming important* controls in reports. Now that I use Reporting Services daily, this practice still holds: ambiguous names like "Textbox1" or "Textbox112" become "ReportName" or "FinalBalance", "table1" becomes "WidgetSalesTable", and "chart1" becomes "MonthlyTrendChart".

As well as better organising the report while in development and adding only a small amount of time to actually do, renaming controls is useful to me later when I'm maintaining a report as I can see which controls contain which data points.

There's one further advantage to renaming controls in a Reporting Services report: because reports are stored in XML format, I can extract the static contents of a control (as long as I know it's name) either from the RDL file or from the RDL file stored as XML in the Catalog table in the ReportServer database.

I recently needed this functionality as I wanted a list of reports with the contents of a textbox on each report body called "Purpose".

This was fairly straightforward to accomplish using the XML nodes() method, which is dependent on the control being sought (which is why there's no code for this blog post, sorry!)

* I don't usually rename controls that contain "meta" information, like column headers and blank cells.

Tags: ,

Reporting Services "Execution xxx cannot be found"

Recently I investigated a Reporting Services problem where a user first ran a report with one parameter, then switched applications to do some work, then returned to the report and attempted to run it with a different parameter. The end result was that they received an "execution xxx cannot be found (rsExecutionNotFound)" error.

I too see this "execution cannot be found" error intermittently, sometimes after coming back to a report I'd run earlier and clicking "Back" or trying to expand a section on the report, and sometimes when my browser loads up tabs from a previous session.

And The Reason Is You

Behind the scenes, Reporting Services tracks each user's session (using an "execution" identifier) in the ReportServerTempDB database, storing report snapshot data and information on selected parameters as well as report sections that are expanded. There's an article "Report Session Caching in Reporting Services 2005" on Database Journal that explains the caching in more detail.

The expiry time for the Reporting Services session is set to 10 minutes by default (note this is different to ASP.NET session and/or connection or command timeouts).

And I Will Try, To Fix You

Although there are multiple ways to alleviate the problem, in my case it was following the advice at Emi Baragan's blog which describes how to modify the session timeout using script. John Gallardo goes into more detail where the session might expire while a user is running a report (that takes longer than 10 minutes to run), which wasn't happening in my case, but is also a potential cause of the "execution cannot be found" error.

John's post ends with a note that keeping sessions alive longer can cause the ReportServerTempDB database to increase in size - something which I'm happy with, but will need monitoring.

Tags: , ,

Two Types of Developers

Recently my boss said something like:

There are two types of developers - ones that are into their tools, and those that just use the tools. You don't need to be the first type to get the job done.

With regards to most of the programs I use, I'm the first type (and proud of it). However there's some things I have no desire to get into, and would rather just use; DOS batch files, Oracle TNSNAMES.ORA configuration, HTML help authoring, to name a few.

That one little quote also touched on a tendency that I have to spend too much time fiddling and fine-tuning. Have you ever downloaded a single-use utility to get a task "just right"? Me too!

Maybe there's some programs that I spend a lot of effort on, that I could afford to take a step back from and just use to get the job done.

Tags: , ,

Setting Focus to Control in an IFRAME using JQuery

Had a gnarly problem this afternoon, while trying to set focus to a control in an IFRAME.

Using JQuery, I had created the IFRAME with the JQuery plugin ThickBox. ThickBox provides functionality that can simulate a modal dialog using an IFRAME, loading a page from a URL into the IFRAME (check out the demo here - scroll down to "Inline Content"). The page loaded inside the IFRAME contained code to set the focus which was actually being called, but after the page loaded something else was stealing the focus.

I began to look at the javascript code in the parent that created the IFRAME.

I discovered to set the focus to a control in an IFRAME that has already been loaded, you need to set the focus to the IFRAME first (thanks Alex King). I also benefited from "How to access IFRAME in JQuery" over at ProCoding (thanks Taras Ilnytskyy).

Here's the code to set focus to a control in an IFRAME using JQuery (called from the parent window, after the IFRAME has been loaded and shown):
	
//get the IFRAME element - note no hashes in the name, we're using browser functionality
var iframeRef = document.getElementById("IFRAMEID");
//focus the IFRAME element
$(iframeRef).focus();
//use JQuery to find the control in the IFRAME and set focus
$(iframeRef).contents().find("#CONTROLID").focus();
I hope this helps someone!

UPDATE: Fixed formatting.

Tags: , , ,
«April»
SunMonTueWedThuFriSat
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910