Once there was a hacker who needed to rescue a beautiful princess from her prison on a creaking ship moored in the middle of the sky.  He made it onto the noisy old ship, slipped past the guards and tiptoed down the swaying halls to the room where she wept, chained to an excel spreadsheet.
“Hello there Princess! I’ve come to whisk you away!”
“My Hero! I can’t leave this spreadsheet till I know that every URL in this column is correct. I’m stuck clicking on each link and it’s terrible! Sometimes Excel does things I don’t want, it is confusing and I fear I’ll be here till I die…”
The hacker thought for a moment and drew from his bag of tricks a magical Ruby that could cut her chains.
# You need to install 2 things to use this tool
# 1. Ruby - http://www.ruby-lang.org/en/downloads/
# 2. WxRuby - once you've installed Ruby, go to Start, Program Files, Ruby, RubyGems, Ruby Gems Package Manager
# Now type gem install wxruby
# 3. you should be ready to run this
require 'net/http'
require 'uri'
require 'win32ole'
require 'wx'
include Wx
class MyApp < App
path_to_wbook = 'C:\temp\file_to_check.xls'
worksheet_with_urls = 'Generic Content'
column_with_urls = 9
file_types = "Excel files (*.xls)|*.xls|New Excel Files (*.xlsx)|*.xlsx"
def get_worksheet(sheet_name, wbook_path)
wbook = open_workbook(wbook_path)
sheet = wbook.Worksheets(sheet_name)
return sheet
end
def open_workbook(wbook_path)
excel = WIN32OLE.new('Excel.Application')
workbook = excel.Workbooks.Open(wbook_path)
return workbook
end
def url_is_good(url)
uri = URI.parse(url)
response = nil
Net::HTTP.start(uri.host, uri.port) { |http|
response = http.head(uri.path.size > 0 ? uri.path : "/")
}
if response.code != "200"
puts "Response code was " + response.code
end
return response.code == "200"
end
def on_init()
file = Wx::FileDialog.new( nil, "Choose a file", "", "", file_types, Wx::OPEN|Wx::CHANGE_DIR|Wx::FILE_MUST_EXIST )
case file.show_modal()
when Wx::ID_OK
puts "File: %s, Directory: %s" % [ file.get_filename, file.get_directory ]
path_to_wbook = file.get_path
when Wx::ID_CANCEL
puts "Starting up with the default workbook"
end
position = Wx::SingleChoiceDialog.new(nil, "Which column are the URLS in?", "URL Column", "ABCDEFGHIJKLMNOPQRSTUVWXYZ".split(//))
position.set_selection(8)
case position.show_modal()
when Wx::ID_OK
puts "Chose column " + position.get_string_selection
column_with_urls = position.get_selection + 1
puts column_with_urls
when Wx::ID_CANCEL
puts "Canceled, going with default"
end
puts "Opening up " + path_to_wbook
sheet = get_worksheet(worksheet_with_urls, path_to_wbook)
for row in sheet.UsedRange.Rows
cell = row.Cells(column_with_urls)
val = cell.text
next if val.nil?
#we need to pull any whitespace from the front or the back of the string
val = val.strip
#if the url doesn't contain % then we should try to escape it.
val = URI.escape(val) unless val.include?('%')
URI.extract(val) do |url|
if url_is_good( url)
#let's clear the cell color
cell.Interior['ColorIndex'] = ExcelConst::XlColorIndexNone
#puts "good: " + url
else
#highlight this cell
cell.Interior['ColorIndex'] = 36
puts "BAD LINK FOUND"
puts "BAD: " + url
end
end
end
puts "Gone through all the urls, saving and closing down now."
sheet.Parent.Close(1)
puts "goodbye!"
end
end
class ExcelConst
end
excel = WIN32OLE.new('Excel.Application')
WIN32OLE.const_load(excel, ExcelConst)
MyApp.new.main_loop()
The princess used the script and it slipped her chains. She took his hand, gave him a kiss, and they escaped down to the city streets. There they went to a nice dinner.
Much thanks to David Mullet’s “Ruby on Windows” blog, where I learned about using win32ole and wxRuby.
