Thursday, June 25, 2009
Absenteeism
For my new website I am planning on more than just a blog, although I'm not quite sure exactly what that means yet. For starters the new site is running an ASP.Net blog engine called BlogEngine.Net (available here) I have created a customized theme for the site, but haven't had much time to do anything else just yet.
So again I bid you adieu from this blogger site and hope to see you on the other side.
Friday, December 01, 2006
Excel: my new favorite program :)
I have an excel spreadsheet with a custom vba function that will simply return the document property with the name given in the parameter. This function works wonderfully. I can enter it as the formula for a particular cell in the worksheet (such as =DocProperty("MyVariable")) and that cell will now display the value of that document property.
Although this does work as expected the first time the cell's value is calculated it does not automatically update if the document property changes. Excel seems to cache the value of each cell. This makes sense for performance issues however I am using DSOFile.dll to update these document properties from another application (namely Qualtrax.) With this setup the values are changed when the document is closed and I would like the new values of these variables to be displayed each time the document is opened.
I have seen similar behavior with "Fields" in Word documents where the displayed value does not correspond to the actual value stored. The solution in Word documents was to add a VBA macro that runs automatically when the document is opened, so I figured I would create a similar macro that would update my Excel documents. I figured something like the following would work:
Public Sub Auto_Open()
Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets
ws.Calculate
Next ws
End Sub
However I wanted to be sure that in the event of a worksheet with a large number of calculated cells I only update the ones that need to be udpated. So I came up with the following code:
Public Sub Auto_Open()
' - This macro will refresh any cells where the formula
' - is a call to the DocProperty function
'
Dim ws As Worksheet
Dim cell As Range
For Each ws In ThisWorkbook.Worksheets
For Each cell In ws.UsedRange.Cells
If InStr(cell.Formula, "DocProperty") > 0 Then
cell.Calculate
End If
Next cell
Next ws
End Sub
Much to my surprise this function did not work. I stepped thorough and discovered that the cell.Calculate call was being made for each cell whose formula was a call to my DocProperty function (shown below), however for some reason Excel is not actually recalculating the value! After a couple hours of torment I found that resetting the formula on the cell will force a recalculate so simply changing cell.Calculate to cell.Formula = cell.Formula fixes the problem and actually makes Excel recalculate the value of that cell. WHY OH WHY does the Range.Caclulate function not actually force a recalculate of a cell whose formula calls a vba function?!?!?
Complete working code.
Public Function DocProperty(property As String) As String
Dim WB As Workbook
On Error Resume Next
If TypeOf Application.Caller Is Range Then
Set WB = Application.Caller.Parent.Parent
Else
Set WB = ActiveWorkbook
End If
DocProperty = WB.CustomDocumentProperties(property)
WB.Saved = True
End Function
Public Sub Auto_Open()
' - This macro will refresh any cells where the formula
' - is a call to the DocProperty function
'
Dim ws As Worksheet
Dim cell As Range
For Each ws In ThisWorkbook.Worksheets
For Each cell In ws.UsedRange.Cells
If InStr(cell.Formula, "DocProperty") > 0 Then
cell.Formula = cell.Formula
End If
Next cell
Next ws
End Sub
Thursday, September 21, 2006
The Wild
Monday, August 14, 2006
Pay it Forward
Oh and in case anyone was wondering the ice cream was delicious! If you are ever in the Southwest Roanoke area I highly recommend stopping by Brusters for a waffle cone!
Fundraisers for Ian Herbst
Sept 11th Arby's in Radford Charity night
Sept 21st Chic-fil-a in Christiansburg Charity night
Oct 24th Texas Roadhouse charity night
If you would like more information about Ian Herbst please check out www.ianfund.com.
Friday, July 28, 2006
Formatting QualTrax dates in Word headers and footers
1) First go to Insert->Field like you normally would to add a QualTrax field to the document.
2) Select DocProperty and then select the field name that you would like to add such as ##DATE_PUBLISHED##.
3) Now before clicking OK to close this window, click the "Field Codes" button in the lower left corner of the window.
4) You should now see a box titled "Field codes:" that should look like "DOCPROPERTY ##DATE_PUBLISHED##" we will need to add the formatting code to the end of this field. First add " \@ " (without the quotes) which tells word that the rest of the text we add is formatting text. If your formatting text will include any spaces you will need to enclose it with double quotes.
5) Next add one of the following formatting codes to get the desired date format.
MM/DD/YYYY => 02/06/1981
M/D/YYYY => 2/6/1981
"DDD M/D/YYYY" => Fri 2/6/1981
"DDDD MMMM D, YYYY" => Friday February 6, 1981
Here's some more information on each of the formatting characters and what they mean.
Year
Displays a year as two or four digits, depending on how many letters 'y’ you use. The letter ‘y’ can be either uppercase or lowercase.
| Parameter | Displays | Example |
y or yy | The year in two digit form, with a leading 0 for years 00 to 09 | 06 or 06 |
yyyy | the year in four digit form | 2006 |
Month
Displays a month as one or two digits, as a three-letter abbreviation or in full, depending on how many uppercase letters ‘M’ you use (lowercase letters ‘m’ represent minutes).
| Parameter | Displays | Example |
M | The number of the month as a number without a leading 0 for single-digit months | 7 |
MM | the month as a two-digit number with a leading 0 for single-digit months | 07 |
MMM | the month as a three-letter abbreviation | Jul |
MMMM | the full name of the month | July |
Day
Displays a day of the month or the day of the week, depending on how many letters ‘d’ you use. The letter ‘d’ can be either uppercase or lowercase.
| Parameter | Displays | Example |
d | The date of the month as a number without a leading 0 for single-digit days | 27 |
dd | the date of the month as a number with a leading 0 for single-digit days | 27 |
ddd | the day of the week as a three-letter abbreviation | Thu |
dddd | the full name of the day of the week | Thursday |
Hour
Displays an hour of the day as one or two digits based on either a 12-hour clock or a 24-hour (military) clock, depending on whether you use an uppercase or lowercase ‘h’. A lowercase ‘h’ bases time on the 12-hour clock. An uppercase ‘H’ bases time on the 24-hour (military) clock. You can also include ‘AM/PM’ in uppercase or lowercase.
| Parameter | Displays | Example |
h or H | The hour as a number without a leading 0 for single-digit hours | >8 or 8 |
hh or HH | the hour as a number with a leading 0 for single-digit hours | 08 or 08 |
am/pm | ‘AM’ or ‘PM’ | AM |
Note: You can change the AM and PM symbols that Word uses by changing the Time settings in the Regional Settings dialog box in the Windows Control Panel. For example, you could use this to force the ‘am/pm’ parameter to display as ‘a.m./p.m.’.
Minute
Displays the minute as one or two digits, depending on how many letters ‘m’ you use (uppercase letters ‘M’ represent months).
| Parameter | Displays | Example |
m | The minute as a number without a leading 0 for single-digit minutes | 43 |
mm | the minute as a number with a leading 0 for single-digit minutes | 43 |
Second
Displays the second as one or two digits, depending on how many letters ‘s’ you use. The letter ‘s’ can be either uppercase or lowercase.
| Parameter | Displays | Example |
s | The second as a number without a leading 0 for single-digit seconds | 10 |
ss | the second as a number with a leading 0 for single-digit seconds | 10 |
Tuesday, June 27, 2006
QualTrax Training
Tuesday, June 06, 2006
Gotta Love Word!
Method 1 (Macro): With this method you would add a macro to each document that would calculate the "Effective Date" based upon the Published Date and store it into a new document variable called ##EFFECTIVE_DATE##. This macro would be setup to run automatically each time the document is opened so that you are always viewing up to date information. the problem with this is that if the person to open this document has their Word security setting set to anything higher than low, they will get a warning message asking them to enable/disable the macros. If they decide to disable the macros within the document, the information will not get updated and they may be looking at an old copy of the data. If you have the document converted to PDF using the PDF Module you will not have this problem.
The steps to implement method 1 are as follows:
1) Open the document in question and go do "File->Properties" and click on the "Custom" tab.
2) In the "Name" field enter "##EFFECTIVE_DATE##" without the quotes.
3) Select "Date" in the "Type" drop-down list.
4) Enter any date in the "Value" field. It doesn't matter what date you enter as this will automatically be overwritten when the macro runs.
5) Click the "Add" button then click "Ok"
6) Insert the field into the appropriate place in the document using the "Insert->Field" command like you normally do.
7) Go to "Tools->Macro->Macros" if you have already entered the "AutoOpen" macro select it and click Edit, if not type "AutoOpen" into the Macro Name field and click the Create button.
8) Overwrite the auto-generated code with the following:
Sub AutoOpen()
Set tmpProps = ActiveDocument.CustomDocumentProperties
dPublishedDate = tmpProps.Item("##DATE_PUBLISHED##").Value
dEffectiveDate = DateAdd("d", 14, dPublishedDate)
tmpProps.Item("##EFFECTIVE_DATE##").Value = dEffectiveDate
Dim aStory As Range
Dim aField As Field
For Each aStory In ActiveDocument.StoryRanges
For Each aField In aStory.Fields
aField.Update
Next aField
Next aStory
ActiveDocument.Saved = True
End Sub
Method 2 (Field Code): With this method you would add in a field using the "Insert->Field" command and put in some custom field codes that will calculate the effective date. This is much more difficult than using the macro because you cannot simply copy and paste the field code into the Word document. Most of it can be copied and pasted however each pair of curly braces {} would have to be entered by pressing ALT+F9 which turns out to be a bit of a pain especially with how long the field codes are.
{QUOTE
{SET Delay 14}
{SET a{=INT((14-{DOCPROPERTY ##DATE_PUBLISHED## \@ M})/12)}}
{SET b{={DOCPROPERTY ##DATE_PUBLISHED## \@ yyyy}+4800-a}}
{SET c{={DOCPROPERTY ##DATE_PUBLISHED## \@ M}+12*a-3}}
{SET d{DOCPROPERTY ##DATE_PUBLISHED## \@ d}}
{SET jd{=d+INT((153*c+2)/5)+365*b+INT(b/4)-INT(b/100)+INT(b/400)-32045+Delay}}
{SET e{=INT((4*(jd+32044)+3)/146097)}}
{SET f{=jd+32044-INT(146097*e/4)}}
{SET g{=INT((4*f+3)/1461)}}
{SET h{=f-INT(1461*g/4)}}
{SET i{=INT((5*h+2)/153)}}
{SET dd{=h-INT((153*i+2)/5)+1}}
{SET mm{=i+3-12*INT(i/10)}}
{SET yy{=100*e+g-4800+INT(i/10)}}
{=dd*10^6+mm*10^4+yy \# "00'-'00'-'0000"} \@ "dddd, d MMMM yyyy"}
I made each of the curly braces in the above code bold so you can tell them apart easier. Again each of these pairs of curly braces must be entered in Word by pressing ALT+F9 rather than typing them in.
You would also need to keep in mind that Word 2003 does not automatically update these fields so in order to force an update in this version of Word you would need to add in a macro that would do this.
Although you do have the security warning to worry about, method #1 would be my recommendation. It would be easier to implement and can easily be copied from one document to another.
*Credit for the Word field codes above goes to Woody's Lounge. See this forum post for more information.
Clear Type: Better readability for all!
Microsoft has an online tool for turning on and tuning your clear type fonts available at http://www.microsoft.com/typography/ClearType/tuner/Step1.aspx. They also have a power toy available at http://www.microsoft.com/typography/ClearTypePowerToy.mspx which will install itself as a control panel applet.
