Tuesday, December 27, 2011

FYI -- Potential downtime

Just a quick note: I'm transferring some domains away from GoDaddy (a long time coming), and this is one of them. If you experience some downtime while I wait for things to switch over, I apologize, but we'll be back up and running soon.

Wednesday, December 21, 2011

Plaintext password offender: Yankodesign.com

I recently created an account at Yanko Design (they have some neat stuff I wanted to further explore).

The welcome e-mail I received was as follows:

Yep, that's my password, in plaintext. Luckily I used a throwaway, but still, come on. What's it going to take for merchants and e-commerce platforms to do better than this?

Monday, December 19, 2011

How To: Insert Group Name Text into a Crystal Reports 2008 Section [Field Notes]

I accidentally deleted the group name text from a section of my Crystal Report in Crystal Reports 2008, and now I would like to re-insert the text.

This is embarrassingly simple, and yet I found it to be surprisingly counter-intuitive. Maybe it's just me..

In the Field Explorer section, expand the "Group Name Fields" section and drag the name onto the report.

It's not under insert, not as a menu shortcut, etc. -- as far as I can tell, the only place to drag a Group Name field from is there.

How To: Toggle Fields in a Crystal Report Based on Whether Records are Returned [Field Notes]

In a Crystal Report, you would like to show or hide sections based upon whether the report contains results or not.

Step 1: Create a Shared Variable and Increment it

  • Create a formula with a shared variable in your report -- for the sake of this example, we'll call it v_RecordCount.
  • The contents of the formula should look like this:
//Excute this formula as records are read into the report
//define a variable that is available throughout the 'main' report
Global Numbervar RecordCount;
//increment the variable
RecordCount := RecordCount+1;

Step 2: Place the Variable in the Report header and Suppress it

  • Drag the formula into the "Report Header A" section.
  • Right-click on the formula you added in the report and select Format Field...
  • Click the Common tab.
  • Check the Suppress button.
  • Click OK.

Step 3: Craft the Proper Suppression Formula for the Sections
Note that the formula we have created will return null when there are no records. This is key to crafting the formula.

  • Right-click on the section you would like to show or hide based on having results.
  • Click Section Expert...
  • Next to the Supress (No Drill-Down) option, click the Formula button.
If you want to hide a section if there are no results, enter the following:
If IsNull({@RecordCount}) then true
else false
This tells Crystal to hide the section if the RecordCount is null (i.e. there are no results), and to show it otherwise.

If you want to show a section if there are no results, enter the following:

If IsNull({@RecordCount}) then false
else true
If (Not(IsNull({@RecordCount}))) then true
else false

These both say "if the record count is not null" (i.e. there are records), suppress this field. Otherwise, show it (if there aren't any results).

Thursday, December 15, 2011

Crystal Reports 2008 Gotcha: Subreports with multiple parameter values [Field Notes]

The Setup

  • I have a report in Crystal Reports 2008.
  • The report uses a few different sub-reports.
  • The report links the subreports to the main report by passing the main report parameter to the subreport parameter.

The Problem

  • When calculating totals, it works correctly if I pass in a single parameter value to the main report.
  • However, if I pass in multiple values for a parameter to the main report (think multiple work order numbers for a WONUM parameter), the subreport calculates totals for all the fields 

The Solution
At first, it seemed like the issue was due to me not resetting the subreport total calculations on each page. But, I knew that I was doing this, and doing it correctly according to multiple reference points.

However, the issue (and thus, the solution) was simpler.

Because I was passing the main report parameter to the sub-report, Crystal was passing all parameters that I passed into the main report into the subreport, so the subreport was being told to calculate across all those values each time.

Instead, I changed the link to the subreport parameter. Instead of passing it the main report's parameter, I passed it the main report field that contained the work order number, thus assuring that it would only receive that one work order as a parameter.

See the StackOverflow discussion for more references and comments.

Wednesday, December 14, 2011

A brief video on the dangers of SOPA / Protect-IP

And this barely begins to cover it. There's a lot beyond this, too.

PROTECT IP / SOPA Breaks The Internet from Fight for the Future on Vimeo.

Please act on this before it's too late for the internet. [Not Hyperbole]

Important enough that I'm giving it space here. PLEASE take action on this.

Tuesday, December 13, 2011

Another Underwhelming Experience With UPS MyChoice

UPDATE: This is entirely my fault. I leave the text below only as a reference and to shame myself. The issue is that UPS sent me an e-mail at 12:07 saying a package would be delivered the next day. Because it was Sunday night, I thought it would be Monday, but it was technically Tuesday at that point because the e-mail had been sent 7 minutes after midnight.

You win this one, UPS. But maybe batch those e-mails to 4 in the morning or so?

Normally, when you pay for extra convenience despite the fact that a service business's reputation is normally based on that coming standard, you would expect a little something extra, right? UPS MyChoice doesn't seem to think so.

I paid $40 for the year to join the service, which promises more convenient options such as holding shipments at the UPS store, delivering shipments to another address, picking a 2-hour delivery timeframe window, etc. This is great, considering the problems I've had with package carriers.

And at first, the service does seem promising. You receive e-mails that tell you when a package is en route to your address, and when it is expected to arrive -- even if you didn't have a tracking number. This e-mail allows you to change options for the package, etc.

So when I received an e-mail Sunday night saying that my winter gloves would be delivered the next day, I was thrilled. I would be at work, and so I needed to have them hold it at a store.

The e-mail said it would be delivered the next day (Tuesday) between 1:15 and 5:15. I received the e-mail at 12:07am, and at 12:08am I had chosen to have it held at the store. I was very excited that this was working out the way it's supposed to. More than I should be, really.

Fast-forward to Tuesday at 4:15pm. I show up at the store where I'd asked the package to be held, but they didn't get any deliveries for the day. I knew it wasn't supposed to be until 5:15 at the latest, so I asked them to track the package -- only to find out that it had experienced a "delivery exception" (a.k.a "we changed your stuff on you, sorry!"). Why? Apparently when I selected the convenient option of having it delivered to the store that day, they conveniently also added an extra day onto the delivery time.

This is exactly what I was trying to avoid. Get an e-mail at 12am saying a package will be delivered at 5pm. Ask them to hold it at the store down the street, but they need an extra day to figure out how to do that? Also, no notification about an updated delivery date, and no e-mail about a package exception at all. So I still made the extra trip, and I still had the package delayed, only this time I was supposed to feel like it was convenient, and pay them $40 a year for the privilege.

Doubt I'll be renewing that subscription, UPS.


████ to ████ on my █████ █████ ████. ███████ ███████ to it! But for now, ████ is ████ █████████. ██████ ████ ████ to ████ on the ████████ and ████████ ███████████ of ████. ██████. ████ ████ ████████. And ████, ████ you (█████████) ███████ ████ I did ████ ████ ███████████ is ███████ of, █████ ████ ████ ████████ it. ███████ █████████, ████ ███████████ ████ ████ won't █████ ███████.


Friday, December 09, 2011

Building a Build Process, Part 1: Introduction

[This is the first article in a series of articles I'll be doing about building a Build Process for an application. You can refer here at any point for all of the published articles in the series.

Under Construction: The language in these posts may be a little terse at first, but I'll be fleshing it out over time -- be sure to check back!]

Articles in This Series

Why Undertake This (Plus: Look at my Presentation!)

I've seen too many instances in various jobs and projects where the build/integration process is not afforded due diligence (or any diligence, really).

I decided I needed to do something about it. Part experiment, part challenge, part reference guide. I'm going to see if I can put together an entire continuous integration / build process for .NET environments from scratch.

Below, you can find some slides from a presentation I gave at work (and yes, the design ideas are at times ripped directly from Zach Holman's article as I tried to emulate his style. He's awesome, and I'm shameless. Credit was given.) This talk highlighted the benefits of inte"great"ion and what I was about to undertake.

My Goal
In short, dear reader, my end desire is to have a completely integrated build process for .NET using (almost) free and/or open-source tools, and to share my process with you.

The build process so far will include the following:

  • Subversion repository on CentOS VM
  • An ASP.NET MVC Project Added to the Source control
  • Trac web site connected to Subversion repository on CentOS VM
  • Build Server VM (Windows Server 2008 R2)
  • CruiseControl.NET running on the Build Server
  • Building the Project with MSBuild via CCNet
  • Building a Release build via CCNet; if successful, publishes to AppHarber via a cloned git repository
  • NUnit Tests
  • NCover code coverage metrics
  • SpecFlow User Acceptance Test / Feature Test coverage
  • Selenium Server as a web driver to execute specflow tests
  • Selenium Grid executing tests on multiple OSes / platforms
  • Adding FxCop to the mix to check my coding standards
  • Adding StyleCop to the mix to make sure the code is consistently written.
  • Utilizing Nuget packages and Octopus to transform releases for different environments.
Hoo-boy, Here We Go
It's a lofty goal -- especially for someone who's not a pro developer -- but I'm excited for everything I'm about to learn during this process.

Onward and Upward!

Feedback Welcome!

I'd love to hear any comments on this series. Find it useful? Think there's a better way to implement the technique or something I should have mentioned? Please drop a line in the comments to help me improve the series!

Thursday, December 08, 2011

Tip: Does your workplace block Google Chat? Use Google+ to talk to people in your circles

[Ed. Note: For the record, I discovered this by accident, and don't particularly intend to use it unless absolutely necessary.]

While circumventing your workplace's chat policy is never necessarily a wise thing, if your office place blocks Google Chat, you can (partially) circumvent this to allow Google Chat with folks in your Google+ circles.

To do so:

  • Sign into Google+.
  • On the home tab, you should see a notification about being able to chat with your circles.
  • Click OK, and your contacts will appear on the home screen with standard gchat-like indicators.
Some things of note so far:
  • Your friends' job titles take the place of chat statuses within Google+ chat.

Tuesday, December 06, 2011

Tip: When presenting, ALWAYS have backup formats [Field Notes]

A brief anecdote:

I prepared a presentation yesterday to present today to colleagues on subjects such as Continuous Integration, Unit / Spec Testing, Source management, etc.

I created the presentation in MS PowerPoint 2010, and saved it with some embedded fonts in .pptx format. It runs great. I open it on my work PC this morning, and it runs great. I save it to a thumb drive, and it opens fine.

We get into the conference room late, I log onto the PC that's there, I open the presentation..
...and PowerPoint crashes.

I try copying it from the USB Drive to the Desktop, I open it ...and PowerPoint crashes again.

Luckily, I saved a version in .ppt format so that it would be backwards compatible with PowerPoint 2000-2003. I open that ...and PowerPoint crashes again.

Luckily, I also uploaded the presentation to SlideShare. I attempt to open that ...and the computer has trouble connecting to the internet.

Luckily, I had also exported the presentation to a PDF file. I open that in Adobe Acrobat Reader, put it in full-screen mode, and gave the presentation.

I hope that illustrates the point well enough without further explanation.

Sunday, December 04, 2011

Fix: Notepad++ Tabs From Your Last Session

Just found myself doing this again on the new setup; figured it might be worth posting.

When opening Notepad++ after previously closing it, the application loads all the old files you were working on last time.

This is by design, and may be useful for some users. If it's not your thing, and you want to remove it:
  • Click Settings --> Preferences
  • Click the MISC. tab
  • Uncheck the box labeled "Remember current session for next launch"

How To: Add Mail Checker plus back to Chrome [Tips]

One of my favorite Chrome extensions -- Mail checker plus -- is in beta and the author decided not to make it publicly available anymore (likely due to supporting users, etc.)

At any rate, found this helpful thread which helps explain how to get the extension back into Chrome, which is useful knowledge in general, so I'm sharing:

  1. Go to: https://github.com/AndersSahlin/MailCheckerPlus/downloads
  2. Click on either the "Download as zip" or "Download as tar.gz" button (most people will probably click on the zip option).
  3. Unzip the file that you downloaded in step 2.
  4. In Chrome, click on the Wrench menu, select Tools, and click on Extensions.
  5. Place a check mark next to "Developer mode."
  6. Click on the "Load unpacked extension" button at the top.
  7. Navigate to where you unzipped the extension and click OK.

Friday, December 02, 2011

Tip: Suppress #DIV/0 errors in Excel with a formula

If you ever receive a #DIV/0 error in Excel that you expect to be there (i.e. calculating percentages from other data which may not have accumulated yet), you can suppress  it by using an IF statement in the formula.

Let's say you have three columns -- A, B, and C. C calculates the percentage of B and A (i.e B/A), but if A is 0 or empty, you'll get the DIV/0 error which throws off formulas, coloring, highlighting, etc.

Instead of :

= B1/A1

Do something along the lines of the following:

=IF(A1=0, 0, B1/A1)


=IF(A1=0, "", B1/A1)

This does a simple check first: If A is zero, it will substitute a default value. Otherwise, your calculation will go on as planned.

I've used this tip many a time to help with the presentation of an Excel sheet.

Thursday, December 01, 2011

SQL Server: Save Not Permitted Dialog Box [Field Notes]

In a new install of SQL Server 2008, when attempting to save changes to a table in a new database, I occasionally get the following error:

Saving changes is not permitted. The changes you have made require the following tables to be dropped and re-created. You have either made changes to a table that can't be re-created or enabled the option Prevent saving changes that require the table to be recreated.

Per this excellent article on MSDN help, take the following steps to rid yourself of this error:

  • Tools --> Options
  • Expand the Designers Section
  • Click the Table and Database Designers section
  • Uncheck the box labeled "Prevent saving changes that require table re-creation."

Don't do this on a production database. Just don't do it. I only needed this for a quick temporary database, or when working in design mode. Otherwise, this option should always be enabled.

Save (Not Permitted) dialog box [MSDN]

Tuesday, November 29, 2011

Fix: VirtualBox doesn't allow to re-name a registered drive and readd to a VM [Field Notes]

In VirtualBox, if you take the following steps:

  • Have HDD1.vdi and HDD2.vdi as storage
  • Remove HDD1.vdi (and delete it) 
  • Rename HDD2.vdi to HDD1.vdi
  • Attempt to add the (new) HDD1.vdi to the VM
You will receive an error along the lines of: 
Failed to open the hard disk [Path to your VDI file].
Cannot register the hard disk [Path to your VDI file] {[UUID of your new VDI file]} because a hard disk [Path to your VDI file] with UUID {[UUID of your old VDI file} already exists.
  • In VirtualBox, select File --> Virtual Media Manager.
  • Click the hard disk in question.
  • Click "Release" and then "Remove to remove from the media library.
You will now be able to add your renamed VDI file.

Fix: CentOS 5.x hangs during VirtualBox install [Field Notes]

Technology Involved
  • Win7 Pro x64
  • VirtualBox 4.1.x
  • CentOS 5.x

When attempting to install a CentOS Guest VM from a VirtualBox Win7 x64 host, the installation appears to hang shortly after beginning.

The last line of text on the screen is:
NET: Registered protocol family 2
Per this thread (referencing an older version of VirtualBox but still relevant), the fix is as follows:
  • Go into the settings of the VM
  • Click the System section.
  • Check Enable IO APIC.
  • Save the settings.
When you start the install again, it will proceed normally.

Monday, November 28, 2011

Update on the New Desktop Setup

This is the desktop, assembled, without the enhanced airflow in the rear and with no overclocking yet.

Windows Experience Score (out of 7.9)
  • Processor: 7.8 
  • Memory (RAM): 7.8
  • Graphics: 7.7
  • Gaming Graphics: 7.7
  • Hard Drive: 6.0 (I think the SSD caching hasn't fully kicked in yet)
PCMark 7 Score: low 4,000 (~4,100? Forgot the actual number)

Standard Temperature: ~89F (hottest of the 5 temp sensors)

Gaming Temp: ~93F (tested with Call of Duty: Black Ops)

Next Steps
  • The "overclockening" -- when I feel like it. It runs smooth like butter now and I have no reason to push it (this is going to be part server, after all)
  • Increasing the air flow
  • Ensuring everything is backed up (Backblaze is chugging along now)
  • Moving media/content from External HDD onto Desktop
  • Erasing External HDD
  • Configuring Windows System backup on HDD
  • Virtualization, and tons of it. Setting up a bunch of systems (more posts on why later)
Also, a Big Thank You
Thanks to John Herron, a former co-worker and excellent techie, I also now have a 20" LCD monitor. The kindness of nerds astounds.

Any ideas for other benchmarks? Let me know!

Notes on Sub-Reports in Crystal Reports 2008 [Field Notes]

For starters, in CR 2008, you can't create two separate groups of data in one report (for example, all labor for a work order and then all materials for a work order).

To do this, you need to create a sub-report, format it, and pass any values back up to the main report using shared variables.

This forum post that I found has a great quick run-down on how to accomplish shared variables from sub-reports to main reports. It was very helpful in understanding the wonky Crystal syntax behind what should be a simple thing.

The post is excerpted (though poorly formatted) below in case the originating site ever goes away:

Shared variables, introduced since Crystal Reports version 7, make it
easier to pass values from a subreport to the main report. 
Using shared variables requires two formulas:
one to store the value in a shared variable, the other to retrieve the
value from the shared variable.
The most important thing to remember when using shared variables is
that Crystal Reports must first evaluate the formula where the value is
stored before evaluating the formula that retrieves the shared variable.
For example if you want to pass a grand total from the subreport to do
a calculation in the main report, follow these steps:
1. In the subreport, create a formula similar to the one below:
//Stores the grand total of the {Orders.Order Amount} field
//in a currency variable called 'myTotal'
Shared CurrencyVar myTotal := Sum ({Orders.Order Amount})
2. Place this formula in your subreport.
3. In the main report, create a formula that declares the same variable name:
//Returns the value that was stored in the shared currency variable called
//myTotal in the subreport
Shared CurrencyVar myTotal;
4. Place @MainFormula in a main report section that is beneath the section
containing the subreport. For the shared variable to return the correct value in the main report,
you must place @MainFormula in a main report section that is beneath
the section containing the subreport. This ensures Crystal Reports evaluates the @SubFormula before @MainFormula.
One way to do this is to insert a section below the section containing
the subreport, and place @MainFormula in this new sub-section:
· On the 'Format' menu, click 'Section'.
· On the 'Sections' list, click the section containing the subreport.
· Click 'Insert' (at top of dialog box). This inserts an additional
· Click 'OK' to return to the report, and insert @MainFormula into this
new subsection.
The next time you preview the report, @MainFormula displays the value
from the subreport.
In this particular example, that value was the grand total of the
{Orders.Order Amount} field. 
5. Once you have verified that @MainFormula is returning the correct
value from the subreport, you can include this formula in other
main report formulas, such as:

//includes data from subreport
{@MainFormula}+ Sum ({Customer.Last Year's Sales})
Place this formula in the same section as @MainFormula, or in a section
further down on the report.

How to Get Formula Field Value From Subreport to Main Report [CodeGuru]

Tuesday, November 22, 2011

New Desktop Rig! [Nerd Toys]

Recently, I decided to invest in something that would meet two very important criteria -- something that would help me advance my career and knowledge, and also something that would be awesome.

The end result -- I'm getting a new desktop rig, and building one from scratch for the first time.
Components in the New Desktop
I've followed largely in the footsteps of the Jeff Atwood build (when someone really smart has already done a lot of research, it's a huge leg up). The components are below, with links:
What I'm Getting For all of This
  • Lots of Power and Speed. A 2600k (let alone an overclocked one) is a beast in terms of power. Add SSD caching, the decent graphics, and the 16GB of memory, and I think this thing is going to fly.
  • Stability / Backups. RAID mirroring the 1TB drives together gives me fault tolerance, and my external backup via Backblaze gives me peace of mind. I'm going to script the hell out of some backups to an external too, I'm sure.
  • Efficiency. The gold-certified PSU has some great resistance to stress, which also means less heat.
  • Future-proofing. The case is big and easily configurable, and once I'm familiar with all the components, I'll have no trouble upgrading them piecemeal.
What I Plan to do With It
  • Get better at doing this sort of thing. Seriously, it amazes me that I've gone this long without building my own rig. It's such a rite of passage in the tech world. I have plenty of knowledge of how these things tend to work, but there's no substitute for doing it.
  • Back it up. The first piece of software to go on this baby after Windows will be Backblaze, which is currently my backup provider of choice. Unlimited data + external HDDs for $50/year. Unbeatable.
  • Overclock it. The word itself makes me nervous and conjures images of silicon melting, but it's apparently mind-numbingly simple with the 2600k.
  • Virtualize on it. 16 GB of memory and all that HDD space means prime virtualization territory. I'll stop short of putting XenServer on it because I still want to play games, etc. natively on Windows, but I plan to use VirtualBox to set up a number of of VMs, which leads me to my next point..
  • Start experimenting. I have so many ideas. I'd say too many, but of course I don't believe in such things. I'm going to be working on Continuous Integration, build processes, development, etc.
  • Find a game to play. I can't tell you when the last time was I played a decent game. Now that I have acceptable graphics output, I'm looking forward to nerding out a bit with some games.
  • Go to dual (and eventually triple) monitors. It's its own reason.
What Do You Think?
Sound off in the comments -- I'm interested to hear your thoughts!

Friday, November 18, 2011

Fix: Crystal Reports 2008: Database Links Happen Automatically and Cause Unnecessary Slow-down [Field Notes]

In Crysal Reports, whenever adding a table from an existing data source, or adding a new datasource, when I click "OK", Crystal automatically switches to the "Links" tab and auto-calculates links.

99% of the time this is something I don't want it to do.

Auto-linking can be turned off in Crystal's options with the Following Steps:

  1. From the File menu, select Options...
  2. Select the Database tab.
  3. Under the Advanced Options section, uncheck "Automatic Smart Linking."
  4. Feel your blood pressure drop to normal levels.

Monday, November 14, 2011

Fixed: Remote Desktop Connection Won't go to Full Screen [Field Notes]

In Windows 7, I am in a Remote Desktop Connection Full screen. I accidentally pop it down to "window" size (i.e. when it can be resized), but the window refuses to go back into Full Screen mode.

On the host machine (not the machine you're remoted into), press CTRL+ALT+Break (or CTRL+ALT+Pause for laptops that don't have a Break key).

On laptops, there may be an extra step. For example, on my laptop, this combination was CTRL+ALT+Fn+Insert (insert doubles as the Pause key on my machine, and Fn is the button to toggle the alternate meaning).

With the right combination of keys, this places Remote Desktop back into full-screen mode.

Thursday, November 10, 2011

Fix: Crystal Reports 2008 Database Explorer Doesn't Show All Schemas [Field Notes]

In Crystal Reports 2008, I am attempting to add a ODBC datasource (connecting to an Oracle 11g database) so that I can change field links, etc.

However, when I go into the Database Explorer and create an ODBC connection, certain system and user schemas show up, but mine is not in the list, despite the fact that I can view and query that schema/user in many other Oracle clients such as SQL Developer or DBVisualizer.

This seems to be a strange bug. According to this helpful (but obscure) forum post, the way to resolve the issue is to:

  • On the menu bar, select File --> Options.
  • Click the "Database" tab.
  • Uncheck the "Stored Procedures" option.
I have no idea why this fixes the issue, but it certainly did. Very happy to have this one behind me.

Crystal Reports 2008 / Business Objects XI: Differing ODBC DataSource Issue [Field Notes]

In Crystal Reports 2008, I create a report using an Oracle connection or an ODBC connection with name x. When I upload the report BO XI, it doesn't work with the ODBC connection added to it.

While annoying, this appears to be because Business Objects doesn't automatically apply its own Data Source, and so any difference that doesn't match up in the server will result in a database error or repeated/endless login dialogs

When using ODBC connections on your BO Server, prior uploading your report, be sure to create an ODBC connection with the same name as the server and set the data source location to it.

This should allow the server connection to stand in for the local connection and remove the Database issues when you run the report in Business Objects XI

Tip: Always Write Out Your SQL Queries in Plain English First [Field Notes]

I recently ran into an issue where constructing a SQL query took me much longer than I would have liked. While my need to dust off some cobwebs and my lack of familiarity with an enterprise system certainly contributed, I think the biggest factor was that -- because I didn't write out what I wanted to accomplish in plain English -- I was attempting to think about my data in the way that the database was thinking.


Consider the difference between just talking about what you want to return and how you will go about doing it. I believe you should do both, but separately, and they should inform each other.

Example: What You Want To Return

  • Summaries for the costs and labor of a work order's child tasks (which are just a special type of work order having the original work order as a parent and a designation of a task)

Example: What Your Process Will Be To Get it

  • I'll get the hours summary, labor cost summary, and item cost summary by task workorder number, by joining the workorder number across workorder, labor, and items
    • I'll Constrain this by making sure the work order is a task
    • I'll call this Work Order Summary
  • Once I have that working, I'll put it on the inside of another set of summaries, by parent so that I can sum up the summaries and have them for each parent work order.
  • Once that works, I'll make sure that all potential null values (summaries) return zero if they come back null.
Suggested Key Phrases
  • "I'll call this... " -- Helps you to decide what your Aliases  / "As" statements should be
  • "I'll get the..." -- Indicator of types of field information you want to return in each record
  • "I'll constrain this by making sure" -- helps define your WHERE clause
  • "Summary" -- helpful to see if you'll be aggregating / grouping
  • "Once that works, ..." -- Helps you to see a testing point, or a place that can stop. 
Additional Benefits

Consider the other practical benefits that writing your queries in plain English will bring:
  • Firstly -- you lose nothing by doing this. That's the biggest thing.
  • You'll find what I call your "test points" -- places where you can stop and insert some hard code for the purposes of testing. 
  • If you can't write it out using plain language, you will be informed early on that you don't understand the data you're dealing with.
  • You can always start over from scratch if the query design doesn't quite work, knowing that you won't lose what you were trying to do.
  • You can ask for help much more easily if you need it, and help your rescuers understand your situation quickly and clearly
  • It automatically self-documents the business language, which means that someone smart on the business side can read it and tell you if you're not understanding the business rules quite right. This can be very helpful if your queries aren't returning what the end-user needs.

Does anyone know where I might find more guides along these lines? Do you have suggestions or improvements? Sound off in the comments!

Wednesday, November 09, 2011

Fix: Crystal 2008 Doesn't Refresh After Adding Columns [Field Notes]


Crystal Reports 2008 Designer does not reflect changes made to views or stored procedures, even after refreshing the database and those views/procedures within Crystal.


While a horrible user experience, there is a proper method to accomplish this.

Based on trips from this helpful article:
  • From the "Database" menu, click "Verify Database".
  • If dealing with a stored procedure, you will be asked to enter parameters; enter correct ones.
  • Crystal Reports will undergo a verification process, during which time it will find the extra fields and adjust the report accordingly.

No idea why this is separate from (and ambiguously named compared to) a right-click and "refresh", but it does the job.

Fix GMail 707 error by disabling Background Send in Google Labs

For anyone who has had an issue with a GMail 707 error in the browser recently, a potentially useful tip via Brad Feld over at FeldThoughts:

The answer was a simple one once I figured it out. I disabled all the Google Labs and it magically started working again. I then re-enabled Labs until I found the one that was causing the 707 error – the “Background Send” Labs. Apparently something broke over the weekend with Background Send and the newest browser version of Gmail.
If you are getting a 707 error, just turn off Background Send. That should fix it.

Thought it might be useful to some.

GMail 707 Error [FeldThoughts]

Friday, November 04, 2011

No Professional Should Ever Be Without a Tide To Go Pen [Field Notes]

Dressed up nicely today for a big meeting with the head of our division at work.

A coworker needed a spoon, and I used it as an excuse to indulge my inner caffeine addict in the cafeteria.

5 minutes after I bought the coffee, it splashed against the side of the container and formed a nice little geyser to land on my light-colored shirt.

Normally, I would have been doomed to a day of embarrassment at a time when I really don't need any. Luckily, this is where Tide to Go comes in.

I keep a TTG pen in my office for just such an occasion. I walked quickly back to my office and used it on a gigantic area of my shirt. It took a few minutes (it was a seriously large area to cover), but was painless.

The end result? By the time I delivered the spoon to my coworker, she couldn't notice any stain.

This product is sheer brilliance. I'm buying 2 more today.

Tuesday, November 01, 2011

Crystal Reports Error: "A subscript must be between 1 and the size of the array." [Field Notes]


A long-standing Crystal Report (being run out of SAP Business Objects XI v12) suddenly started generating an error along the lines of:

Error in File [File Name]: Error in formula [Formula Name]: 'left(split({[Field Name]},"/")[2],3)'
A subscript must be between 1 and the size of the array.
Details: errorKind

(The bracketed values were specific to the report itself)


In this case, the formula is looking for a "/" to split the string. On a hunch, I decided to query the database, and sure enough, some of the fields in the database had been modified and no long included a "/", causing the formula to bomb out.

Two solutions here:

  • If the "/" is a business requirement and is supposed to be there, modify the data.
  • Otherwise, modify the formula to include branching logic that takes other steps if a "/" is not detected.

Monday, October 31, 2011

iPhone 4S / iOS 5 battery issues? Turn off time zone settings

The excellent folks over at Lifehacker have a tip that seemingly works to resolve iPhone 4S and iOS 5 battery level issues.

The culprit? It looks to be a bug in the Time Zone settings that causes location services to go nuts and poll way more often than it needs to, draining the battery.

To remedy the issue, according to Lifehacker:
The solution for now seems to be manually switching off the automatic time zone updates located at Settings -> Location Services -> scroll to bottom to System Services -> Setting Time Zone. Expect more conclusive results in the coming weeks.
I've tried it and saw an immediate and striking difference in battery life. Give it a shot if you haven't yet. And if you're jet-setting anytime soon, just re-enable it (or take me with you and I'll do it for you!)

iPhone 4S Battery Problems May Be a Bug with iOS Location Services | Lifehacker

Tuesday, October 25, 2011

Re-show the Outlook Envelope Icon [Field Notes]

I hid the Outlook envelope by accident, thinking it was temporary. Of course, it isn't.

To get it back:

  • Tools Menu --> "Options"
  • Click the "E-Mail Options" button.
  • Click the "Advanced E-Mail Options" button.
  • In the "When new items arrive in my Inbox" section, check the "Show an envelope icon in the notification area" checkbox.
  • Click okay to confirm the various options screens and you'll be back in business.

Tuesday, October 18, 2011

From GMail to Outlook: Making it Feel Like Home for GTD [Field Notes]

I recently started a new job at the Johns Hopkins Applied Physics Laboratory in Laurel, MD. It's a great gig so far, but one of the pain points I hadn't expected was moving from Google Apps to Outlook. I had a system in GMail that worked perfectly for my brain, but I needed to find a new solution. This post details how I got myself back to my organizational "happy place".

[Ed. Note: I'll try to get some screenshots on this soon. Let me know if they'd be helpful to you more immediately.]


I really liked my GMail system, so I wanted to keep the basics. I decided that the following were "must-have" capabilities:

  • Labels: This has been indisputably the best feature of GMail for me. Assign labels that stand for categories, statuses, references, etc. -- I needed to recreate that experience, with distinct colors if possible.
  • The Archive Button: After I've labeled and sorted my mail, I need to get it out of my inbox and into an Archive folder. A button is best suited to this task.
  • Seeing Status Messages and counts: It's important to me to be able to do a quick review of what I need to do next, what I'm waiting on from folks, etc. In GMail, I used multiple inboxes with status labeled to achieve this effect. 

Step 1: Defining Categories and Hot Keys
I created three sets of Categories to start with, and assigned each a different color.

Status Categories
These start with "S/" and are orange in color. I defined the following:
  • S/Next Action
  • S/Action
  • S/Waiting On
  • S/Follow-Up
  • S/Someday
  • S/Finished
Project Categories
These start with "P/" and are green in color. I defined one for each project I'm involved with.

Reference Categories
These start with "R/" and are purple. I defined the following:
  • R/General
  • R/Credentials
  • R/Accomplishments
My next steps will likely be to define context categories (C/) and Vendor Categories (V/) once I start having interactions that would benefit from them.

I then assigned hot keys to each of the status categories. This can be done from the Categories List. I assigned the following Hotkeys:
  • S/Next Action -- CTRL + F2
  • S/Action -- CTRL + F3
  • S/Waiting On -- CTRL + F4
  • S/Follow-Up -- CTRL + F5
  • S/Someday -- CTRL + F6
  • S/Finished -- CTRL + F2
Step 2: Creating an Archive Button
Thanks to this excellent article at Lifehacker, I was able to create an Archive button similar to Gmail's. The steps I took (slightly different from the article) are below.

Create an Archive Folder in your Outlook Mailbox
Under the top-level folder of your mailbox, create an "Archive" folder on the same level as Inbox, Junk E-Mail, Outbox, etc.

Create a Digital Signature for VBA Projects
This is necessary to avoid a macro warning pop-up everytime you do something in Outlook. Highly recommended.
  • Open the "Digital Certificate for VBA Projects" utility (start typing it into the start menu and it should come up).
  • Follow the steps to create a certificate. I either named it "Me" or "Sean Killeen", I forget which.
Creating the Macro
  • Select Tools --> Macro --> Macros from the menu
  • Type in the name for your Macro (e.g. "Archive Button") and click Create.
  • When the VBA Editor opens, enter the following script:
Sub Archive()

    Set ArchiveFolder = Application.GetNamespace("MAPI").GetDefaultFolder(olFolderInbox).Parent.Folders("Archive")

    For Each Msg In ActiveExplorer.Selection
        Msg.UnRead = False
        Msg.Move ArchiveFolder
    Next Msg

End Sub

This script marks the message as read and puts it in your archive folder.

Step 3: Creating Search Folders for Monitoring Statuses
Next, I used search folders to help me monitor different statuses. Unfortunately, the best way to create these search folders is to use the QueryBuilder, which Microsoft for some unfathomable reason has disabled by default.

After a finding a great article on TechnoSpot, I answered my own question on SuperUser 

Enabling QueryBuilder in Outlook 2007 via a Registry Hack

  • Run regedit in your run command or via Win + R
  • Navigate to HKEY_CURRENT_USER\Software\Microsoft\Office\
    • If you have Outlook 2007 navigate to the 12.0 folder
  • Right click on Outlook and Add a new key. Name it as QueryBuilder
  • Exit Registry editor.
Creating the Advanced Query
The process below is using the "S/Next Action" category as an example. Repeat it for each of your Status categories.
  • In Outlook, select the "Tools" menu --> "Instant Search" --> "Advanced Find"
  • Click the "Query Builder" tab (which did not exist before our registry hack)
  • Define the first criteria
    • Field: "Categories"
    • Condition: "contains"
    • Value: "S/Next Action"
  • Define the second criteria
    • Field: "Categories"
    • Condition: "Doesn't Contain"
    • Value: "S/Finished"
  • Select the logical group
    • From the "Logical Group" drop-down, select "AND". This is key to making sure that Outlook enforces all the criteria (which is not normally the case; hence this post)
  • Set the Scope to of the Search to the Desired Level
    • In the "Look for:" drop-down, select "Messages" (likely already selected)
    • Click "Browse"
    • Make sure all appropriate folders are selected (I chose the entire mailbox)
    • Check the "Search Subfolders" checkbox
  • Save the Query as a Search Folder
    • In the Advanced Find window, click "File"
    • Click "Save as Search Folder" and name the Search Folder.
Customizing Folder Positions and Showing all Messages
In order to be able to move the folders as we like (instead of being locked into alphabetical order), we make the folders "Favorite Folders.
  • Right-click on each of the Status folders and choose "Add to Favorite Folders". This will place the folder in the top list of folders.
  • Order the list as you want in favorite folders -- I usually place them in my order of importance, which is:
    • Next Action
    • Action
    • Waiting On
    • Follow-Up
    • Someday
  • Right-click each status folder and select Properties
  • In the properties window, select "Show total number of items."
The Results!
Not "home", per se, but at least a comfortable apartment.

Below is a recap of the list of resources that helped me solve this problem.

Robocopy: "You do not have the Backup and Restore Files user rights" [Field Notes]

[Ed. Note: "Field Notes" is a place where I plan to succinctly describe solutions to problems that I run across in my daily work. They are meant as a reference; ask if you have any questions!]

In Windows 7, Using Robocopy with the /B or /ZB switches yields the error "You do not have the Backup and Restore Files user rights".

This is due to UAC. Either run the command prompt as an administrator (with appropriate credentials) or ensure that your scheduled task has appropriate credentials.

Friday, October 07, 2011

Password Rules Offender: Charles Schwab


Dear Charles Schwab,

It is 2011. Why do you have a maximum length of 8 characters on an account password? And why is the only requirement that there be a number between letters?

It does not inspire confidence when I am about to ask you to hold my money.

Update: It also doesn't allow symbols. That's right, folks; maximum of 8 characters, and only letters/numbers. I can't believe this crap.

Update: Two-Factor Authentication Available!
Thanks to Richard Smiley who wrote in the comments to alert us to the fact that Schwab is now offering a two-factor authentication token upon request.

For more details, head to the SchwabSafe Page. As of the time of this update (2/21/2013), to request a token, call Schwab at 800-435-4000.

Tuesday, September 27, 2011

Bizarre. Never thought I'd see the day when my office e-mail was empty. End of an era.

Friday, September 23, 2011

Random musing on password storage in webapps

A (loosely-formed, potentially already-implemented) thought:

For security's sake, it's blasphemous to store passwords in plain-text; using a hash function and then doing a re-hash and comparison is considered much better.

But, if bad guys steal your database, they still could brute-force against the hash and conceivably retrieve many passwords.

The question I have is: Is salting a hash as effective for the effort as say, combining multiple encryption methods with a signifier?

For example, Let's say MD5 = 1, DES = 2, and AES = 3. During the first time the password is stored, why not generate a random sequence of these numbers (i.e. "231"). Then, hash the password in that order (e.g. for "231", DES, then AES, then MD5) and add the digits to the front. Then, comparison does all three hashes in a random way, by taking the first three digits to see how it should be decoded.

I know this is more computationally expensive than a salt, but given the random algorithm assignments plus the task of brute forcing (and taking into account that the attacker would have to have source-code access to see your enum of what numbers are what, etc.), would it be more effective?

Update: In case you'd like to follow along, I posted the question to the StackExchange Security site, so that people much smarter on this than me could weigh in.

Tuesday, August 30, 2011

A Birthday Gift to the World: Let's Give Others Clean Water!

I'm a lucky guy, and I've had by all standards a great and fantastic 25 years so far. I've got most things I could want in life, and everything I need.

I wish it was the case everywhere, but it's not; the fact of the matter is, some on this Earth still lack the basic necessities for survival. Every once in a while, I'll dump some of a glass of water down the sink, and I'll remember that in some places it's still considered a precious commodity.

It doesn't have to be that way.

And so, I'm giving up birthday gifts again this year to try to make a difference. With your help, I was able to raise $281 last year, and I'd like to see if we can top it this year.

Please consider donating at http://mycharitywater.org/seans25th for my 25th birthday. I'll appreciate it, but the people who will have clean water to drink will appreciate it even more.

Charity:Water is one of the most accountable, transparent organizations I've ever seen, and I hope you'll add your charity as we work to help the world.

Thursday, August 18, 2011

Troubleshooting: HP PhotoSmart B-209a Wireless Printer Driver "Fatal Error During Installation"

I recently re-installed Windows 7 x64 on my laptop due to purchasing an SSD. I expected fantastic speed & performance, more productivity, etc.

What I didn't expect was for HP Driver setup to make me want to tear my hair out.

What follows is a brief and too-technical tale of how I vanquished the foe, for my own reference. If you're less-than-technical or think they could help you, just ask me for details or screenshots in the comments and I'll be happy to provide them.

The Problem
HP Driver setup for a wireless printer already configured on your network yields a generic "Fatal Error During Installation" message. Though my Antivirus/Firewall were disabled and I ran the downloaded installer as Administrator, I still received the message whenever I ran the setup program.

Applies To

I have not tested this in any other environments, so I'm assuming it applies to:

  • HP PhotoSmart B-209a printers that have already been configued on the wireless network.
  • Win 7 Professional 64-bit

The Solution Steps

  1. Disable Your Antivirus Applications (Firewalls are OK). Though not the root cause of the issue, Antivirus programs can still muck with the process. Best to temporarily disable. Firewalls on the other hand, you would like to have running so that you can ensure you allow the network connections necessary for the device.
  2. Take ownership of your local temp directory. I did this by running the command "takeown /f C:\Users\[Username]\AppData\Local\Temp\ /r /d y" where [Username] is your own username.
  3. Remove all restrictive attributes from the Temp directory. This can be done by running "attrib -R -A -S -H C:\Users\[Username]\AppData\Local\Temp /S /D" where [Username] is your own username.
  4. Find where your installation is located in the Temp directory. For me, it was "C:\Users\[Username]\AppData\Local\Temp\7zS08A6" where [Username] is your username. The exact folder may be different but I'm hoping they kept it the same.
  5. Run the actual setup program as Administrator. Within the installation directory you found in the last step, right-click on setup.exe and select "Run as Administrator".
With those steps (and a little bit of luck and/or voodoo magic) the install should complete successfully. 

Hope this helps someone! If you have any questions or would like more detail, feel free to ask in the comments.

Happy Troubleshooting!

Thursday, April 14, 2011

Free Million Dollar Idea: Package Carriers + B2B = Success

I'll try to keep this post brief or see if I can sketch it out in bullet-points.

My Current Situation

Like many people:
  • I live in an apartment
  • I work during the day
  • I often work different or longer hours than standard business hours (i.e. before 9am and after 6pm)
  • My work often requires my physical presence / prevents me from leaving to get a package

The Beef I Have With Package Carriers

  • They force you to sign for packages.
  • Sometimes, after you sign, they say they still can't deliver.
  • All apartments are considered unsafe by default it seems.
  • Carriers don't trust your authorization to drop the package, even when expressly written and signed.
  • Carriers don't stagger their delivery times (i.e. if they try before 10:30am on Monday, they'll try before then on Tuesday and Wednesday too). This doesn't help pick up a package.

The Business Problem

This isn't necessarily all the carrier's fault; they have things they need to abide by as well.

The business problem, as I see it, involves the following:
  • Carriers have SLAs with their shipping partners (guaranteed dates/times of delivery, etc.). This can be very helpful sometimes (i.e. every package will arrive next day by 10:30). However, if the customer is not available at that time, the SLA can actually hamper delivery.
  • Carriers have a responsibility for goods (so they don't want to leave them in "dangerous" areas)
  • Customers need to pick up packages in a way that works with their schedule

How I Think They Could Fix it

I think that package carriers are missing an important opportunity here -- the ability to partner with other businesses to help customers receive their package.

Let's think about a scenario like this:

  • Customers can specify an intermediary business for delivery. Think national chain businesses that are open outside of 9-5 hours. Lots of restaurants (McDonalds, Subway), box stores (Walmart, Costco, etc.), and grocery stores (Giant, Acme) fall into this category.
  • Customers either could pay a fee to use this intermediary or the carrier could offer it as an option, and could select the intermediary. This is especially of benefit if a customer wants to group purchases, e.g. "I'll pick up my package and get groceries!"
  • Businesses create space for a holding area for packages and accept the responsibility of an intermediate carrier (i.e. responsible for lost/damaged packages, etc.). Businesses will protect this because it's linked to their business reputation and customers chose them for a reason. They have a stake in quality.
  • Carriers drop off a consolidated shipment according to their SLAs.

Benefits to All Parties

Businesses --
  • Businesses receive some cash (either from carriers or from the fee to hold the package there)
  • But more importantly, businesses also receive a chance at customer purchases while they're there. Impulse buys, combining purchasing ideas, etc. For example, if I could pick up a package and my groceries from Whole Foods and not at giant, guess who's getting my grocery dollars.
  • Stronger relationship with a national carrier driving business to the store.

Shippers --
  • Less logistical concerns -- they drop the packages off at businesses, businesses handle from there.
  • Could be a good corporate partnership -- think of a store devoting some space to a UPS kiosk, for example. Branding in visible places.
  • Could actually save money -- less trucks, less driving, less re-delivering packages, less info notice slips, and most importantly, less logistical overhead in returning to sender.
  • Stronger relationship with stores -- customers more likely to choose you if you offer shipment to businesses they frequent.
Customers --
  • Pick up packages when it's convenient to do so.
  • Huge convenience gain; knock errands out in one shot.
  • Know that your package will be delivered (businesses are open + they have an agreement)
  • You're notified when a shipment is delivered, so you know you can pick it up.
  • Knowing the business will be open outside of standard 9-5 business hours; you don't have to be frustrated simply because you have a job, and you don't have to negotiate a break to sit and wait for a package.

What do you think?

So, could this ever work? What would you change about it? Sound off in the comments; I'd love to discuss!