2012-08-27

ucsd single sign-on does not allow saving password

if you go to ucsd and frequently log into sites that use their single sign-on page such as my tritonlink, you must have noticed that their log on page has the username/pid field set as a password field, so it looks like you're logging in with two passwords.  this tricks browsers into thinking you aren't logging in to something but possibly just changing your password, so it doesn't prompt to save your login info.  ucsd thinks they know what's best for you, but if you keep your computer physically secure and always lock your computer (windows key + 'L') before you leave, then why not save your password?

well you can with the help of either keepass password safe (mostly for pc), or lastpass online password manager.

in keepass, you can set up auto-type on an entry.  make a new entry, type your pid (eg A09...) for the username, and type your ucsd password.  the title of the entry should be nothing other than "ucsd".  now hold ctrl+alt+'a' (for "auto") when you're at the single sign-on page.  keepass will see that you're on a window that contains "ucsd" in the title and will automatically type your username, {tab}, your password and {enter}as if you typed it on your keyboard.

if you want to use lastpass, just install their extension for firefox, chrome, safari or even internet explorer.  sign in once and it'll prompt you to save the password -- lastpass is the only one smart enough to ask.

DataRow keeps converting values into strings

when i use DataRow.ItemArray or the DataRow's indexer (eg myDataRow[0] = ...) to set the values to objects, the values are converted to strings.

DataRow row = ...;
row[0] = (object)5;

//problem:
//row[0] == "5"
//row[0] != 5

the solution is to specify the type on the DataTable's column.

DataTable t = ...;
t.Columns[0].DataType = typeof(object);

2012-08-13

easily open csv files as all text fields with vbs send-to

when excel opens csv files, it will try to infer the data types of the cells based on the data in the file.  however, sometimes it gets it wrong. for example with zip codes, it will think they are plain numbers and remove leading 0's.

to open a csv file as text in excel 2007 or 2010, you can click on the data tab and click from text.  the text import wizard will let you click on each column and specify that it should be a text column so excel won't mess with the data.

it's clumsy to use the text import wizard every time you want to open a csv file with all the columns read as text.  my solution was to add an item to the "send-to" menu.  whenever you right click on a file in explorer, there's a "send to" menu, and you can add custom items to this menu.  i added a script that imports the file into excel.



here's how to set it up:

  1. open notepad
  2. paste the script at the bottom
  3. click file / save as...
  4. for the file name, type %userprofile%\AppData\Roaming\Microsoft\Windows\SendTo\openCsvAsText.vbs
  5. click save

now to use it, right click on a csv file, and click "send to" and then click openCsvAsText.vbs

that's it!

note:  the script actually opens the file twice.  first, it uses OpenText to open the csv file like normal.  then, the contents of the sheet is cleared (but the file is not saved).  then it uses the text import wizard to import the same data, but with different parsing options.  this is necessary because neither function does everything:  first, OpenText ignores the FieldInfo parameter when the file extension ends in "csv" -- it only listens when it's a "txt" file.  second, if you just use the text import wizard, then when you go to save the file, it will ask you where to save it like it's a new workbook.  this is because you'd literally be creating a new workbook and importing some data, which is not the same as opening the data directly.  so, we open the data directly, then import on top with the correct settings.

i would love to hear if this helped you.

here's the script:



Option Explicit

Const xlTextFormat = 2
Const xlTextQualifierDoubleQuote = 1
Const xlDelimited = 1
Const xlOverwriteCells = 0


'when using the send-to menu, windows explorer passes the filename of the right-clicked file
'as a command line argument to the application used to open the file in the send-to folder,
'in this case "Microsoft Windows Based Script Host".  this is the program that runs .vbs files.
'this program makes the filename command line argument available to this script via
'WScript.Arguments.Ietm(0).

Dim filename
filename = WScript.Arguments.Item(0)


'we need specify each column individually.  this says that the first 500 (0-499)
'columns should be read as text.  we will use fieldInfo later.

Dim fieldInfo(499)
Dim i
For i = 0 To UBound(fieldInfo)
    fieldInfo(i) = xlTextFormat
Next


'start excel, with no screen updating because it would flicker around
'while opening the file the second time (we read from the file twice
'due to limitations of excel).

Dim objExcel
Set objExcel = CreateObject("Excel.Application")
objExcel.Visible = True
'objExcel.ScreenUpdating = False 'optional

'open the file, so when we save it later, it knows where to save

Dim objWorkbook
objExcel.Workbooks.OpenText(filename) '.Add
Set objWorkbook = objExcel.ActiveWorkbook


'clear the contents of the file, because we opened it with all the default (wrong) settings

Dim objWorksheet
Set objWorksheet = objWorkbook.Worksheets(1)
objWorksheet.UsedRange.ClearContents

'set format of *all* cells to text, so when we import, we don't have
'the imported cells as "text" but the rest of them as "general".
objWorksheet.Cells.NumberFormat = "@"

'do the equivalent of using the text import wizard, but change some options:
'-RefreshStyle: overwrite cells instead of making room
'-PreserveFormatting: got rid of it
'-AdjustColumnWidth: set to false

Dim m
Set m = objWorksheet.QueryTables.Add("TEXT;" & filename, objWorksheet.Range("$A$1"))
m.FieldNames = True
m.RowNumbers = False
m.FillAdjacentFormulas = False
m.RefreshOnFileOpen = False
m.RefreshStyle = xlOverwriteCells
m.SavePassword = False
m.SaveData = True
m.AdjustColumnWidth = False
m.RefreshPeriod = 0
m.TextFilePromptOnRefresh = False
m.TextFilePlatform = 65001 'UTF-8. for "OEM United States" use 437
m.TextFileStartRow = 1
m.TextFileParseType = xlDelimited
m.TextFileTextQualifier = xlTextQualifierDoubleQuote
m.TextFileConsecutiveDelimiter = False
m.TextFileTabDelimiter = False
m.TextFileSemicolonDelimiter = False
m.TextFileCommaDelimiter = True
m.TextFileSpaceDelimiter = False
m.TextFileColumnDataTypes = fieldInfo
m.TextFileTrailingMinusNumbers = True
m.Refresh False


'the contents now should be the contents already in the file,
'so marked as saved so it does not prompt to save if no
'changes are made.

objWorkbook.Saved = True


'done.

objExcel.ScreenUpdating = True

2012-08-11

excel macro to re-order / rearrange columns by column name


in excel, you can easily write scripts to reorder and delete columns using just the column names (specified in the header row -- row 1) using the below vba macro i made.

for example, to make a simple macro that delete's the "name" column:

be sure to read the documentation in the comments to learn how to do more.


i'd love you to comment if this helped you or if you need help using the script.

Sub RearrangeColumns()
    If ConfirmFormat Then
    
        '==================================================================
        '
        ' type how you want to rearrange columns below.
        ' here's what you can do:
        '
        ' delete a column
        '    to delete the "site_dir1" column, type
        '    DeleteColumn "site_dir1"
        '
        ' move a column to a location specified by letter
        '    to move "pmt_descrp" to column "A", type
        '    MoveColumn "pmt_descrp", "A"
        '
        ' move a column before another column
        '    to move "pmt_class" before the "site_addrs" column, type
        '    MoveColumnBeforeOtherColumn "pmt_class", "site_addrs"
        '
        ' move a column after another column
        '    to move "site_addrs" after the "pmt_class" column, type
        '    MoveColumnAfterOtherColumn "site_addrs", "pmt_class"
        '
        ' then you have to run the macro on the spreadsheet and then save.
        '
        '==================================================================
        
        '........type here......

        


        
        '==================================================================
        '==================================================================
        
    End If
End Sub



Private Function ConfirmFormat() As Boolean
    Dim result As Boolean
    
    result = True

   ' you can use this function to make sure the spreadsheet
   ' you're working with didn't already have its columns
   ' reordered, or at least make sure it's the correct type of
   ' spreadsheet that your macro is made for.

   ' If Cells(1, 1) <> "expected name of column A" Then
   '     result = False
   ' End If
   ' 
   ' If Cells(1, 2) <> "price" Then
   '     result = False
   ' End If
   ' 
   ' If Cells(1, 3) <> "item name" Then
   '    result = False
   ' End If
   '
   ' If Cells(1, 4) <> "date" Then
   '     result = False
   ' End If
    
    If result = False Then
        MsgBox "this spreadsheet is not in the expected format.  you may have already re-ordered the columns in the spreadsheet."
    End If
    
    ConfirmFormat = result

End Function





'***************************************************************************************

'you do not need to change any code below to use this macro.


'***************************************************************************************



Function AddOne(ByRef lngN As Integer) As Integer
    lngN = lngN + 1
    AddOne = lngN

    ' this function let's you specify the order of columns you want sequentially,
    ' starting at column A, like so:
    '

    ' Dim nextNumber As Integer
    ' nextNumber = 1
    '
    ' MoveColumn "const_type", ColumnLetter(AddOne(nextNumber)) 'col A
    ' MoveColumn "site_cnty", ColumnLetter(AddOne(nextNumber)) 'col B
    ' MoveColumn "site_city", ColumnLetter(AddOne(nextNumber)) 'col C
    ' MoveColumn "site_stnam", ColumnLetter(AddOne(nextNumber)) 'col D

End Function

Private Sub DeleteColumn(ColumnName As String)
    DeleteColumn2 FindColumn(ColumnName)
End Sub

Private Sub MoveColumn(NameOfColumnToMove As String, MoveBeforeCols As String)
    MoveColumnBeforeOtherColumn2 FindColumn(NameOfColumnToMove), MoveBeforeCols
End Sub

Private Sub MoveColumnBeforeOtherColumn(NameOfColumnToMove As String, NameOfColumnToPutBefore As String)
    MoveColumnBeforeOtherColumn2 FindColumn(NameOfColumnToMove), FindColumn(NameOfColumnToPutBefore)
End Sub
Private Sub MoveColumnAfterOtherColumn(NameOfColumnToMove As String, NameOfColumnToPutAfter As String)
    MoveColumnBeforeOtherColumn2 FindColumn(NameOfColumnToMove), FindNextColumn(NameOfColumnToPutAfter)
End Sub

Private Sub DeleteColumn2(Cols As String) 'eg Cols = "A"
    Columns(Cols & ":" & Cols).Delete Shift:=xlToLeft
End Sub

Private Sub MoveColumnBeforeOtherColumn2(ColsToMove As String, MoveBeforeCols As String)
    If ColsToMove <> MoveBeforeCols Then
        Columns(ColsToMove & ":" & ColsToMove).Cut
        Columns(MoveBeforeCols & ":" & MoveBeforeCols).Insert Shift:=xlToRight
    End If
End Sub

Private Function FindColumnX(Name As String, Offset As Integer) As String
    Dim Col As String
    
    For i = 1 To 255
        If Cells(1, i) = Name Then
            Col = ColumnLetter(i + Offset)
            Exit For
        End If
    Next
    
    If Col = "" Then
        
        MsgBox "Can't find column '" & Name & "'.  Make sure you the spreadsheet is in the correct format."
    
        End 'stop processing spreadsheet
        
    End If
    
    FindColumnX = Col
    
End Function
Private Function FindColumn(Name As String) As String
    FindColumn = FindColumnX(Name, 0) 'offset = 0 means just find the column like normal
End Function
Private Function FindNextColumn(Name As String) As String
    FindNextColumn = FindColumnX(Name, 1) 'offset = 1 means get the column AFTER this column
End Function


'i got this ColumnLetter function from freevbcode.
'before you re-publish, check their licensing permissions page.
Function ColumnLetter(ByVal ColumnNumber As Integer) As String
        '
        'example usage:
        '
        'Dim temp As Integer
        'temp = Sheets(1).Range("B2").End(xlToRight).Column
        'MsgBox "The last column of this region is " & _
        '        ColumnLetter(temp)
        '
            
    If ColumnNumber <= 0 Then
        'negative column number
        ColumnLetter = ""
        
    ElseIf ColumnNumber > 16384 Then
        'column not supported (too big) in Excel 2007
        ColumnLetter = ""
        
    ElseIf ColumnNumber > 702 Then
        ' triple letter columns
        ColumnLetter = _
        Chr((Int((ColumnNumber - 1 - 26 - 676) / 676)) Mod 676 + 65) & _
        Chr((Int((ColumnNumber - 1 - 26) / 26) Mod 26) + 65) & _
        Chr(((ColumnNumber - 1) Mod 26) + 65)
    
    ElseIf ColumnNumber > 26 Then
        ' double letter columns
        ColumnLetter = Chr(Int((ColumnNumber - 1) / 26) + 64) & _
                Chr(((ColumnNumber - 1) Mod 26) + 65)
    Else
        ' single letter columns
        ColumnLetter = Chr(ColumnNumber + 64)
    
    End If
End Function

2012-08-03

css border shorthand, does order matter?

does the order of the style, width and color specified in a css border matter?
ie, is style="border: 1px solid black"
the same as style="border: black 1px solid"?

i had trouble finding the answer online, hence this post.

but from what i found, plus some experimentation, the answer is:

no, the order does not matter.