Monday, December 3, 2007

Min-height fast hack (IE6 sucks)

Blatantly plagiarized from http://www.dustindiaz.com/min-height-fast-hack/:

selector {
min-height:500px;
height:auto !important;
height:500px;
}

Monday, November 5, 2007

T-SQL IP octet split

Found a neat piece of T-SQL that can be used to separate the octets of an IP address:

Declare @IP varchar(20)
Select @IP = '239.147.8.165'
select @IP AS IP,
cast(substring(@IP, 1, charindex('.', @IP) - 1) as int) AS Octet1,
cast(substring(@IP, charindex('.', @IP) + 1,
charindex('.', @IP, charindex('.', @IP) + 1) -
charindex('.', @IP) - 1) as int) as Octet2,
cast(reverse(substring(reverse(@IP), charindex('.', reverse(@IP)) + 1,
charindex('.', reverse(@IP), charindex('.', reverse(@IP)) + 1) -
charindex('.', reverse(@IP)) - 1)) as int) AS Octet3,
cast(reverse(substring(reverse(@IP), 1, charindex('.', reverse(@IP)) - 1)) as int) as Octet4

The source for this is http://www.umachandar.com/technical/SQL6x70Scripts/Main.htm
.

Thursday, October 18, 2007

Auto-refresh an ASPX page

This is especially useful when using a master page but you don't want every page using the master page to refresh.

In the Page_Load() event handler, add this code:

'Refresh the page every 30 seconds.
Dim lit As New LiteralControl("<meta equiv=""refresh"" content=""30"" />")
Header.Controls.Add(lit)

Sunday, October 14, 2007

Startup object must be a form when "Enable Application Framework" is checked.

If you're reusing a form and are trying to make it the main form of an application, and you get this error, ensure that the constructor for the form takes no arguments.

Tuesday, August 21, 2007

Programmatically open Access and show a table

Just a note on one way of accomplishing this:

Dim objAccess As Object = CreateObject("Access.Application")
objAccess.OpenCurrentDatabase(strFileName)
objAccess.Visible = True
objAccess.DoCmd.Maximize()
objAccess.DoCmd.OpenTable(strTableName)

Wednesday, August 15, 2007

Console and Windows Form in the same application

I recently needed to write a program that had an attended and unattended mode:

1. Create a console application in Visual Studio .NET.

2. Use this as a template:

Module Module1

    Sub Main()
        If Command$() = "-winform" Then
            Dim frm As New testform()
            Windows.Forms.Application.Run(frm)
        Else
            Console.WriteLine("this is the console option")
        End If
    End Sub

End Module

Saving window settings in My.Settings

This is useful for saving window position and size when an application closes and then restoring these settings when the application starts again.

1. In app.config, create three new settings:
- IsMaximized (Boolean)
- MainFormPosition (System.Drawing.Point)
- MainFormSize (System.Drawing.Size)

2. In the form's Load event handler, add the following code:

If My.Settings.MainFormPosition <> Nothing _
        AndAlso My.Computer.Screen.Bounds.Contains(My.Settings.MainFormPosition) Then
    Me.StartPosition = FormStartPosition.Manual
    Me.Location = My.Settings.MainFormPosition
    Else
    Me.StartPosition = FormStartPosition.CenterScreen
End If
If My.Settings.IsMaximized <> Nothing _
        AndAlso My.Settings.IsMaximized Then
    Me.WindowState = FormWindowState.Maximized
Else
    Me.WindowState = FormWindowState.Normal
End If
If My.Settings.MainFormSize <> Nothing Then
    Me.Size = New Size(Math.Max(100, My.Settings.MainFormSize.Width), Math.Max(100, My.Settings.MainFormSize.Height))
End If

3. In the form's FormClosing event handler, add the following code:

If Me.WindowState = FormWindowState.Maximized Then
    My.Settings.IsMaximized = True
    My.Settings.MainFormPosition = New Point(Me.RestoreBounds.Left, Me.RestoreBounds.Top)
    My.Settings.MainFormSize = New Size(Me.RestoreBounds.Width, Me.RestoreBounds.Height)
Else
    My.Settings.IsMaximized = False
    My.Settings.MainFormPosition = Me.Location
    My.Settings.MainFormSize = Me.Size
End If

Turning off auto-scrolling in a bound DataGridView

I was running into an issue where I didn't want the grid to auto-scroll or change the selected row when the underlying DataSource property was changed. Here's what I came up with:


' dgv is a DataGridView control with SelectionMode set to FullRowSelect and MultiSelect set to False.
Dim intSelectedIndex As Integer = 0
If dgv.SelectedRows.Count > 0 Then
    intSelectedIndex = dgv.SelectedRows(0).Index
End If
Dim intDisplayIndex As Integer = dgv.FirstDisplayedScrollingRowIndex
' Set dgv.DataSource here
dgv.ClearSelection()
If intSelectedIndex < dgv.Rows.Count Then
    dgv.Rows(intSelectedIndex).Selected = True
Else
    dgv.Rows(dgv.Rows.Count - 1).Selected = True
End If
If intDisplayIndex > -1 Then
    If intDisplayIndex <>
        dgv.FirstDisplayedScrollingRowIndex = intDisplayIndex
    Else
        dgv.FirstDisplayedScrollingRowIndex = dgv.Rows.Count - 1
    End If
End If

Tuesday, July 31, 2007

Adding a Recent menu to your application

An easy way to implement a Recent menu in your application is to use the My.Settings namespace and store the recently opened items in a StringCollection setting.

1. Create a setting called RecentDocuments of type System.Collections.Specialized.StringCollection.
2. Add the following methods to your form class:

Private Function GetRecentDocuments() As StringCollection
'StringCollection can be stored in XML - it's easier than maintaining five
'separate strings
in the settings collection, because the StringCollection
'can be manipulated all at once

If My.Settings.RecentDocuments Is Nothing Then
My.Settings.RecentDocuments = New StringCollection()
End If
Return My.Settings.RecentDocuments
End Function

Private Sub AddRecentDocument(ByVal strPath As String)
GetRecentDocuments()
If My.Settings.RecentDocuments.Contains(strPath) Then
'If this document was already in the recent list, move it to the top and
'slide everything else down

My.Settings.RecentDocuments.Remove(strPath)
ElseIf My.Settings.RecentDocuments.Count = 5 Then
'If the recent document list is full, drop the last one
My.Settings.RecentDocuments.RemoveAt(4)
End If
My.Settings.RecentDocuments.Insert(0, strPath)
End Sub

3. Add a Recent menu somewhere on your form (I usually make this a submenu under File).
4. In the Form.Load event, call GetRecentDocuments() and iterate through the strings, creating submenu items for the Recent menu.

Dim intI As Integer = 1
For Each strPath As String In GetRecentDocuments()
Dim tmi As New ToolStripMenuItem("&" + CStr(intI) + " - " + strPath)
RecentToolStripMenuItem.DropDownItems.Add(tmi)
intI += 1
Next


5. When an item is opened, pass the appropriate string to AddRecentDocument() and rebuild the Recent menu based on the new StringCollection.

MDI Application Quick Start

Here's what needs to happen to get an MDI application up and running:

1. Set the form's IsMdiContainer property to True.
2. Create a menu strip for the form.
3. Create a Window menu in the menu strip.
4. Set the menu strip's MdiWindowListItem property to the name of the Window menu.

Always refer to the topmost window with a reference to the main form's ActiveMdiChild property.

When a new child window is created, set its MdiParent property to the main form.

Friday, July 13, 2007

Error inserting images into Word document

On calls to Range.InlineShapes.Add("C:\blah.jpg") and Range.Shapes.Add("C:\blah.jpg") I kept getting a very helpful, precise error:

The server threw an exception.
(Exception from HRESULT: 0x80010105 (RPC_E_SERVERFAULT))

Thanks for that!

After playing around with the code for awhile, I found that my particular problem was being caused by how I instantiated the Word.Document object. My code read:

Dim mobjWordApp As New Word.Application()
mobjWordApp.Visible = False
Dim objDocSet As Word.Documents = mobjWordApp.Documents
Dim objDoc As Word.Document = objDocSet.Add(Visible:=MsoTriState.msoFalse)


Removing the Visible parameter from the Documents.Add() call fixed the error. It was unnecessary anyway, since I had already set Application.Visible to False.

Friday, June 29, 2007

Unmanaged DLLs and string (or char*) output parameters

I wrestled with this one for awhile, but discovered (via Google) that you can use StringBuilder to allocate a fixed-length string, then pass the StringBuilder in by value to the exported function/method in the unmanaged DLL. Strings don't work in this case because they are not fixed length, and access violation errors can (and usually) occur.

Declare Ansi Function Function_Name Lib "lib.dll" (ByVal strGoingIn As String, ByVal strComingOut As StringBuilder) As Integer

Viewing exports for a DLL

Open a Visual Studio Command Prompt, navigate to the directory of the DLL to inspect, and use the following command:

dumpbin /export whatever.dll

Friday, June 15, 2007

More on Oracle execution plans

Another useful command in looking at Oracle execution plans is:
set autotrace traceonly explain

Query plans in Oracle (EXPLAIN PLAN)

Discovered this article when looking up how to view a query plan in Oracle.

Thursday, June 14, 2007

How to determine owners of Oracle tables

I recently needed to find out the schema names of certain Oracle tables that belonged to schemas other than the connecting user. This is because the four-part queries in SQL Server require the schema/owner name of the tables referenced. This query (run in SQL*Plus) lists the owners and names of all tables that can be seen by the connecting user:

SELECT OWNER, TABLE_NAME FROM ALL_TABLES;

A full reference for the ALL_TABLES view can be found here.

Friday, June 1, 2007

Casting to NUMERIC/DECIMAL with E notation

Found this neat tidbit on some other guy's blog. Basically, NUMERICs/DECIMALs are exact numeric types and cannot contain the E notation in their representations. FLOATs are approximate numeric types and can contain the E notation. FLOATs can also be CASTed to NUMERIC/DECIMAL with no problems (other than a loss of precision).

For example, take the VARCHAR value X = '10000000E-2'. To cast it to NUMERIC/DECIMAL, use the following:

SELECT CAST(CAST(X AS FLOAT) AS NUMERIC(15, 4))...

You would obviously lose some precision if you cast with a NUMERIC field of less precision than what is represented by the contents of the VARCHAR value.

Truncate the last n bytes of a file

Use FileStream.SetLength():

Dim strFile As String = "C:\Path\To\File.txt"
Dim fi As New FileInfo(strFile)
Dim fs As New FileStream(strFile, FileMode.Open, FileAccess.Write)
fs.SetLength(fi.Length - n)
fs.Flush()
fs.Close()

Thursday, May 24, 2007

Opening a Windows Explorer window in VB.NET

Use Process.Start:

Dim ps As New ProcessStartInfo("explorer")
ps.Arguments = "C:\Directory\to\open"
Process.Start(ps)

Friday, May 18, 2007

.NET Regular Expression Escape Characters

\w - matches any word character
\W - matches any non-word character
\s - matches any whitespace character
\S - matches any non-whitespace character
\n - newline
\f - formfeed
\r - carriage return
\t - tab
\v - vertical tab
\0x0020 - space
\d - digit
^ - beginning of string
$ - end of string

Tuesday, February 13, 2007

Filling in gaps in incrementing INT column in SQL Server

Suppose you have a unique integer column i in a table T. i may contain gaps. i contains m rows.

Suppose you wish to insert n values into i starting at some value x0 and incrementing. Let x equal the first integer greater than or equal to x0 not found in i.

In general, this can be solved by performing the following:

SELECT TOP n * 2 IDENTITY(INT, x, 1) AS j
INTO #temp
FROM T T1
CROSS JOIN T T2
GO

INSERT INTO T (i)
SELECT TOP n j
FROM #temp
LEFT OUTER JOIN T
ON T.i = #temp.j
WHERE T.i IS NULL
GO

There should now be m + n rows in T.

Thursday, January 25, 2007

Getting System Icons into a PictureBox control

A simple solution for getting system icons into a PictureBox control at runtime is to set the PictureBox's Image property to SystemIcons.xxxxxx.ToBitmap().