S Anand

Dilbert search engine

Wouldn’t it be cool to be able to search through the Dilbert archives using text?

This used to be possible at Dilbert.com some years ago, as a paid service. In late 2003, I needed to find some Dilbert strips for a client, so I’d subscribed for a year. I could then search for the quotes (I happened to be looking for "outsourcing", so you can guess the context).

But I can’t seem to find the feature any more, even as a paid service. The site looks a lot better, of course. But I can’t find strips.

Well, why not type them out? After all, I’d done that with Calvin and Hobbes.

This would be a much larger exercise, though. And I’m hoping to take your help. I’ve set up a site at dilbert-search.appspot.com. You can type in a comic randomly, starting from 2000. These will be made searchable on my Dilbert page. You can export the data and use it yourself, of course.

When typing in Calvin and Hobbes, I did have a few volunteers willing to pitch in, but collaboration tools weren’t easy to set up, and I ended up typing the whole thing myself. This time, I’d be delighted if even 10 people typed in just a strip each.


So, here’s my request, to all you Dilbert fans.

  1. Please go to dilbert-search.appspot.com
  2. Log in using your Google account and type in as many strips as you like
  3. Bookmark it for the future, whenever you’re bored

As I said, the data is readily exportable from the page, so if you’re looking to do cool mash-ups with it, great! And if you want the data exported in other formats, please let me know.

Incidentally, I created the site using Google AppEngine. The source code is at dilbert-search.googlecode.com.

Downloading online songs

You know those songs on Raaga, MusicIndiaOnline, etc? The ones you can listen to but can’t download?

Well, you can download them.

It’s always been possible to download these files. After all, that’s how you get to listen to them in the first place. What stopped you is security by obscurity. You didn’t know the location where the song was stored, but if you did, you could download them.

So how do you figure out the URL to download the file from?

Let’s take a look at MusicIndiaOnline first. When you click on a song, it pops up in a new window. You can’t figure out the address of that window because the address bar is hidden, but you can get it by hovering over the link before clicking, or by right-clicking and copying the link location. It’s always something like this:

http://www.musicindiaonline.com/p/x/FAfgqz0HzS.As1NMvHdW/

It always has the same structure: http://www.musicindiaonline.com/p/x/something/. Let’s call that the something the song’s key.

Now, what this page does is play a .SMIL file. An SMIL file is a text file that has a list of songs to play. This file is always stored at

http://www.musicindiaonline.com/g/r/FAfgqz0HzS.As1NMvHdW/play2.smil

(Notice that the key remains the same.) If you type this into your browser, you’ll get a text file that you can open in Notepad. You’ll find that it has a bunch of lines, two of which are interesting. There’s one that reads:

<meta name="base" content="http://205.134.247.2/QdZmq-LL/">

The content="…" part gives you the first part of the song’s address. Then there’s a line that reads:

<audio src="ra/film/…"/>

The src="…" part gives you the rest of the address. Putting the two together, you have the full URL at which to download the song.

Except, they’re a bit smart about it. These songs are meant to be played on RealPlayer, and not downloaded. So if you try to access the page using your browser, you get a 404 Page not found error. But if you typed the same page into RealPlayer, you can hear the song play.

To actually download the song, you need to fool the site into thinking that your browser is RealPlayer. So first, you need to get a good browser like Firefox. Then download the User Agent Switcher add-on. Change your user agent to "RMA/1.0 (compatible; RealMedia)" and try the same song: you should be able to download it.

Let me summarise:

  1. Right-click on the song you want to play, and copy the URL
  2. Extract the key. In the URL http://www.musicindiaonline.com/p/x/FAfgqz0HzS.As1NMvHdW/ the key is FAfgqz0HzS.As1NMvHdW
  3. Open http://www.musicindiaonline.com/g/r/<your_key>/play2.smil in your browser. Open it with Notepad
  4. Switch the user agent on your browser to "RMA/1.0 (compatible; RealMedia)"
  5. Put the content="…" and audio src="…" pieces together to form the URL
  6. Type the URL and save the file

I’ve automated this in my music search engine. So if you go to the Hindi, Tamil or any other online music page and click on the blue ball next to the song, you’ll see a menu with a download option. The download opens a Java program that does these steps for you and saves the song in your PC.

So now, you’re probably thinking:

  1. How did he figure this out?
  2. What about other sites?
  3. How does that Java program work?
  4. How do I listen to these on my iPod?

How did I figure this out?

Fiddler.

I believe a good measure of a tool’s power is it’s ability to be the one-word answer to a relatively broad question. For example, "Where can I find more about something?" "Google it." "How do I improve my pictures?" "Photoshop it".

Fiddler’s like that. "How do I find out what I’m downloading?" "Use Fiddler".

It’s a proxy you can install on your machine. It automatically configures your browsers when you run it. Thereafter, it tells you about all the HTTP requests that are being sent by your machine. So if you patiently walk through the logs, you’ll find all the URLs that MusicIndiaOnline or any other site uses, as well as the other headers (like User-Agent) that are needed to make it work.

What about other sites?

I’ll list a couple here.

Smashits:

  1. Right-click on the song you want to play, and copy the URL
  2. View the source and hunt for the URL fragment "player/ra/ondemand/launch_player.cfm?something".  The key is is something.
  3. Open http://ww.smashits.com/player/ra/ondemand/playlist.asp?6;giftsToIndia1.rm;1,something in your browser, using Notepad
  4. Switch the user agent on your browser to "RMA/1.0 (compatible; RealMedia)"
  5. Type in what’s inside the src="…" in your browser and save the file

Oosai:

  1. Right-click on the song you want to play, and copy the URL
  2. View the source and hunt for the URL fragment onclick="setUsrlist(something)".  The key is is something.
  3. Open http://www.oosai.com/oosai_plyr/playlist.cfm?sng_id=something in your browser, using Notepad
  4. Switch the user agent on your browser to "RMA/1.0 (compatible; RealMedia)"
  5. Type in the URL that you see in Notepad and save the file.

Try figuring out the others yourself.

How does the Java program work?

It does most of these steps automatically. The applet itself is fairly straightforward, and you can view it here. It takes two parameters: db, which indicates the server from which to download (M for MusicIndiaOnline, S for Smashits, etc.) and num, which is the key.

But in order for an applet to be able to download files from any site, and to be able to save this on your PC, it needs to be a signed applet. Since Sun offers a tool to sign JAR files, this wasn’t much of an issue.

There is one pending problem with Windows Vista, however. Signed applets can’t save files anywhere on Vista. They are saved in a special folder. This is being fixed, but until then, if you use Internet Explorer on Vista, you probably will be unable to find your saved files.

How do I listen to these on my iPod?

The saved files are in RealMedia format. Your best bet is to convert them to MP3 files using MediaCoder. Then transfer them using iTunes.

MGR songs quiz 1

Here is the first interlude and the first line from some MGR songs. Can you guess which movie they are from?

Don’t worry about the spelling. Just spell it like it sounds, and the box will turn green.

Gadgets

Some gadgets I’ve bought / got over the last few years.


SDHC Card Reader on 17 March 2009

16GB USB Flash Drive on 8 Jan 2009

16GB SD Card on 14 March 2009

USB MIDI cable on 30 Dec 2008

Creative Labs EP-630/A Earphones on 30 Dec 2008

Recta Micro Compass Accessory on 30 Dec 2008

Strand iPod Cassette adapter on 30 Dec 2008

Keysonic Compact Notebook Layout Wireless 2.4Ghz Radio Frequency Keyboard With Integrated Touch Pad on 6 Sep 2008

TomTom ONE v3 Great Britain on 31 Aug 2008

BlackBerry Curve 8320 on 10 Aug 2008

Acer Aspire 5715Z Notebook Laptop, Intel Pentium Dual Core T2330 1.6GHz, 15.4″ TFT, 2GB RAM, 80GB Hard-drive, DVD±RW, Intel Graphics Media Accelerator X3100, WiFi, Vista Home Premium on 29 Jul 2008

BlueNEXT BN-909 GPS Receiver SiRF Star III on 6 Jul 2008

TDK Recordable Blank 16x DVD+R Discs 25pack Cakebox on 6 Jul 2008

Sandisk MicroSDHC 4GB Card in 6 Jul 2008

HTC S620 (Excalibur) on 1 Jul 2008

Masterplug 4 Gang Switched Extension Lead 2m 13 Amp Fused on 31 Mar 2008

TRUST HU-4440P 4 PORT USB2 MINI HUB on 31 Mar 2008

Hama Compact USB 2.0 Hub 1:4 on 31 Mar 2008

Nintendo Wii Remote on 1 Mar 2008

Sandisk 2GB Secure Digital Card on 29 Feb 2008

Canon IXUS 70 Digital Camera – Silver (7.1MP, 3x Optical Zoom) 2.5″ LCD on 29 Feb 2008

Verbatim DVD+R 25Pk 16x Spindle on 15 Feb 2008

Western Digital My Book Essential 500GB External USB 2.0 Hard Drive on 15 Feb 2008

LUPO DIGITAL TV DVB-T USB ADAPTER/DONGLE/STICK FREEVIEW RECEIVER & AERIAL FOR PC AND LAPTOP on 6 Jan 2008

Bontempi Keyboard – 61 Full Key GM, Midi, Stereo (AD177.12) on 4 Jan 2008

Mini-Headphone Splitter (Stereo) on 1 Jan 2008

Microsoft LifeCam VX-6000 on 26 Dec 2007

Kenwood FP580 Food Processor 2 Speed White on 26 Dec 2007

SanDisk Sansa m240 1Gb MP3 Player on 24 Jul 2007

Sennheiser CX300 Eco Ear Canal Headphones Black on 24 Jul 2007

Uniross AAA 1000mAh (4)Rechargeable Battery Ni-Mh on 24 Jul 2007

Logitech EX110 Wireless Desktop on 5 Mar 2007

Cordless Skype Phone Kit NON VISTA on 5 Mar 2007

LG 42PC1D 42″ Plasma TV on 20 Jan 2007

Sony Ericsson Standard Travel Charger (UK) CST-13 on 12 Jan 2007

Uniross Sprint 1 Hour Battery Charger inc 4 x AA 2700 mAh Rechargeable Batteries – batteries upgraded from 2500 mAh on 11 Jan 2007

Fuji FinePix S5600 Zoom Digital Camera [5.0MP,10xOptical Zoom] on 17 Nov 2006

Fuji 1GB XD Type M Picture Card on 17 Nov 2006

DIGIHOME DVB915 FREEVIEW Digital Terrestrial Receiver with SCART Lead on 17 Nov 2006

Sony 80min/700MB Thermo printable CD-R spin 50pk on 28 Jul 2006

CyberHome DVD 401/0 Multi-region Capable DVD Player with DIVX on 28 Jul 2006

Rivision DVD+R 8x 4.7Gb 100 Cake Box on 15 Jun 2006

Dynamode 3.5″ IDE Interface Disk Enclosure on 1 May 2006

SANDISK CRUZER MICRO 1GB on 3 Jan 2006

BenQ 16x External Dual Format, Double Layer DVD Writer – EW162I, Beige on 3 Jan 2006

Emtec DVD+R Cake Box 100pk on 3 Jan 2006

Panasonic NV-GS17B MiniDV Digital Camcorder [24x Optical, 2.5″ LCD, DV out] on 9 Nov 2005

VoIP rates

While hunting for a VoIP service to call India, I found a fair variety of services that I’m sharing below.

FreeCall appears the cheapest when calling India, at 2.5¢ per minute to a land line. I’m listing the rate from London to Chennai below. I’m not sure of the difference in voice quality between these. The only one I’ve tried is VoIPDiscount, which is not too bad. As a benchmark, remember that Reliance offers a calling card at around 7.3¢ per minute.

(Incidentally, if you wanted to call the US/UK, there’s no reason why you should use your phone. Calls to the US, the UK and parts of Europe are free with most of these services.)

2.5¢/min freecall
3.3¢/min calleasy
3.3¢/min webcalldirect
3.9¢/min net2phone
4.2¢/min smsdiscount
5.0¢/min internetcalls
5.0¢/min nonoh
5.0¢/min voipdiscount
5.0¢/min voipwise
5.5¢/min freshtel.net
5.9¢/min pc-telephone
6.0¢/min mywebcalls
6.7¢/min 12voip
6.7¢/min justvoip
6.7¢/min poivy
6.7¢/min sparvoip
6.8¢/min gtalk2voip
7.1¢/min vbuzzer
7.5¢/min webphone
7.9¢/min yahoo
8.0¢/min click4
8.0¢/min callserve
8.0¢/min hotfoon
8.2¢/min blasterphone.net
8.4¢/min netappel
8.4¢/min sipdiscount
8.4¢/min voipbuster
9.1¢/min voipstunt
9.9¢/min iconnecthere
9.9¢/min lowratevoip
10.0¢/min phoneopia
10.6¢/min skype
11.4¢/min sipnet
11.6¢/min voipcheap
13.8¢/min wengophone
14.6¢/min gizmo5
16.1¢/min peneo
19.9¢/min voipbusterpro

Tamil songs quiz 2008

Here is the background music from some songs from 2008. Can you guess which movie they are from?

Don’t worry about the spelling. Just spell it like it sounds, and the box will turn green. (One spelling is tricky. Try M instead of N at the end.)

Split text

This is a series on what Google Spreadsheets can do that Excel can’t.

SPLIT(string, delimiter) splits a string using a delimiter. So if you have "one,two,three,four" in cell A1, you could split that into 4 cells using =SPLIT(A1,",")

3.1

That’s similar to Data > Text to Columns, except that if the original data changed, Text to Columns does not revise the output. SPLIT can give you dynamic text-to-columns. This is pretty useful when processing text data, in three ways:

  1. You retain the original data
  2. You don’t need to re-apply Text to Columns. Extending the formula will work (and that’s quicker)
  3. It’s dynamic. If the data changes, your split changes

Since SPLIT returns an array, you can do a bunch of useful things with it.

=COUNTA(SPLIT(A1," ")) gives you the number of words in a string

=SUM(SPLIT(A1,",")) sums up a comma separated list. "1,2,3,4" is added up to 10.

=ARRAYFORMULA(SUM(LEN(SPLIT(A1,",")))) sums up the word lengths. So "one,two,three,four" splits into 4 words of length 3,3,5,4 each, which adds up to 15.

The ability to join and split also lets you sort by multiple keys. For example, say you had income by country and product. You want to show it sorted by Country & Product. You also want to show it by Product & Country.

So first take the data sorted by Country and Product.

3.2

Now, in column E, create a key that’s sorted by Product and then by Income. Type

=SORT(ARRAYFORMULA(B2:B10&":"&A2:A10&":"&C2:C10))

… in cell E2. That will give you all the data in one cell, sorted by Product and then by Country. Now, just split the data, as shown here.

3.3

Note: You could have done the whole thing using one formula:

=ARRAYFORMULA(SPLIT(SORT(ARRAYFORMULA(B2:B10&":"&A2:A10&":"&C2:C10)),":"))

But for some reason, this doesn’t seem to show the first row properly. No idea why.

Can I do that in Excel?

Well, not really. You’re best off creating a user-defined function to duplicate the SPLIT function.

Dynamically sort data

This is a series on what Google Spreadsheets can do that Excel can’t.

To sort data, use the SORT function.

For example, if you have a list of products, their revenues and profits in A2:C9. Type SORT(A2:C9, 2, FALSE) in cell E2 to get the products sorted by the second column, revenues.

2.1

This is a dynamic list. If you change the revenues, the products are reordered automatically.

The first parameter to the SORT function is the data range you want to sort. The remaining parameters are optional. The second parameter is the column to sort by. By default, the data is sorted by the first column, in ascending order. In this example, we sorted by the 2nd column. The third parameter is FALSE for descending order, and TRUE for ascending order.

You can specify additional columns to sort by. Just add the second column number and the order, third column number and order, and so on.

For example, this formula sorts by the 2nd column (ascending), 4th column (descending) and 1st column (ascending):

=SORT(A1:D100, 2, TRUE, 4, FALSE, 1, TRUE)

You can create a dashboard with multiple views. Say you wanted to show the above data, and also summarise the top 3 products by revenue and profitability. Go to cell E2, and type

=NOEXPAND(SORT(A1:A9, B2:B9, TRUE))

This sorts the products (A1:A9) using the revenues (B2:B9) in ascending order (TRUE or 1). This would show all 8 products. If you want to keep only the top 3, you need to put the NOEXPAND around the formula. Otherwise, even if you delete the 4th product, Google will put it back.

Now, delete all but the top 3 products. Similarly, in cell E7, type

=NOEXPAND(SORT(A1:A9, C2:C9, TRUE))

This sorts by profitability instead. That’s it! You have a dynamic list of the top 3 products by revenue and profitability.

2.2

Can I do that in Excel?

Excel doesn’t have a function to sort. You can sort a list in-place. That changes the order permanently. There’s no way of retaining the original order.

You could make a copy of the list and sort it. But the copy will not change when the original list changes.

If the length of the list is fixed, and the values you want to sort by are unique, you could use the LARGE/SMALL, INDEX and MATCH functions to simulate this effect. First, type the numbers 1-8 in column D. Then type this formula in F2:

=LARGE(B$2:B$9,D2)

This will give you the largest revenue figure. Copy this down the column. This will show the largest revenue figures in descending order. Now, fill cells E2 downwards with the formula:

=INDEX(A$2:A$9,MATCH(F2,B$2:B$9,0))

The MATCH function finds the revenue in the first table, and the INDEX function looks up the corresponding product. You can use the same principle to get the profitability. However, this will not work if two products have the same revenue figure.

2.3

Keyword searches as a Web command line

Andre’s mentions dumping Google Chrome because of lack of extension support, especially Ubiquity, and lists 15 useful Ubiquity commands.

If you haven’t seen Ubiquity, you should. It’s a great extension that transforms your browser into an Internet command prompt. It is modelled on the Enso Launcher, which is a great piece of work by itself.

I wasn’t quite prepared to let go of Chrome that easily. On Task Manager, seeing 10 Chrome processes, the largest of which takes up 60MB, is a lot more comforting, psychologically, than 1 Firefox process taking up 300MB. (I rarely hit my 1GB RAM limit, so it shouldn’t matter either way. Yet, the spendthrift in me keeps watching.)

So the question is, can I do all the items on his list without using Ubiquity?

Let’s pick the easiest. Google search. If you typed "g some words" on Ubiquity, you get the Google search results for "some words". But you already have that. If you have Firefox, typing any words on the address bar automatically does a Google search for you. On Internet Explorer, it search live.com, but you can easily change that by installing the Google Toolbar.

But the great thing is that this can be customised. On Firefox, click on the down arrow icon next to the search box and select "Manage Search Engines…" to see a list of your search engines. Select the one you want to use, click on "Edit Keyword…" and select the keyword you want. For instance, I’ve typed "google".

Manage Search Engines Add Keywords

So when I type "google some words" on the address bar (not the search bar, the address bar) I get search results for "some words". These are called keyword searches.

On Firefox, you add your own search engines, but you do that using bookmarks. Press Ctrl-Shift-B (Organize Bookmarks) and create a New Bookmark. You can type in any URL in the location field. If you type "%s" as part of the URL, that will be replaced by the search string. So for instance, using a location http://en.wikipedia.org/wiki/Special:Search?search=%s and the keyword "wiki" will do a Wikipedia search for "Harry Potter" if you type "wiki Harry Potter" on the address bar.

It works on Internet Explorer as well, even with version 6. The easiest way is to download TweakUI. Go to Internet Explorer – Search. Click on the Create button. Type in a keyword (called Prefix) and a URL. If you type "%s" as part of the URL, that will be replaced by the search string.

TweakUI

On Google Chrome, get to the Options (what, no shortcut key?) and in the Basics tab, click the Manage button. Here, you can click on "Add" to add a search engine.

Chrome

So that takes care of all the basic searches: Google, Amazon, IMDB, Wikipedia, etc.

Can we go further? Item 8 on the list caught my attention:

Twit. As much as I love full-featured Twitter clients like TweetDeck, nothing beats the simplicity of hitting Ctrl-Space and typing twit [message] to so_and_so, or sending a selection of text using twit this to so_and_so. At the moment, there’s no way to receive tweets or ping Twitter for new messages.

I don’t use Twitter, but I do use Identi.ca, and I would like something like this. Right now, I’m using Google Talk to update identi.ca. Two problems. I don’t like chatting, and logging on exposes me to a lot of distraction. Secondly, I’d rather not have to open an application just for this. Something in the browser would be perfect. But is it possible?

Identi.ca (and Twitter, and most micro-blogging services) let you update via e-mail. So if I could write a program that would mail identi.ca, I should be done. So I did that with a Perl script.

my $q = new CGI;
open OUT, "|/usr/sbin/sendmail -t";
print OUT join "\n",
    "From: my.authenticated.id@gmail.com",
    "To: 1234567890abcdef@identica.com",
    "Subject: \n\n",
    $q->param('q');

So if I placed this at www.s-anand.net/identica (no, I haven’t placed it there), I just need to create a keyword search with a prefix Tidentica" that points to www.s-anand.net/identica?q=%s. Then I can type "identica Here is a message that I want to post" on the address bar, and it gets posted.

Actually, if you can write your own programs, the possibilities are endless. If you’re looking for someone to host this sort of thing for free, Google’s AppEngine may be a reasonable point to start.

But the real power of this comes with Javascript. Those URLs that you saw for keyword searches? Those can be Javascript URLs. So item 9 on the list

Word count. As a student of copywriting, I’m frequently curious about an article’s word length. Highlighting the desired text and entering word count into Ubiquity will give you just that.

… might just be possible.

It’s easy to get the selection. The following snippet gives you the current selection. (Tested in IE 5.5 – 8, Firefox 3 and Google Chrome. Should work for Opera, Safari.)

document.selection ? document.selection.createRange().text :
window.getSelection ? window.getSelection().toString() : ""

To get the word count, just split by white space, and count the results:

s = document.selection ? document.selection.createRange().text :
    window.getSelection ? window.getSelection().toString() : "";
alert(s.split(/\s+/).length + " words")

Now, this whole thing can be made into a keyword search. Let’s call it count. If I go to the address bar and type "count it", I want to use count the words in the selection. If I typed "count some set of words here", I want to count the words in "some set of words here". Here’s how to do that.

javascript:var s = "%s";
if (s == "it") {
  s = document.selection ? document.selection.createRange().text :
      window.getSelection ? window.getSelection().toString() : "";
}
alert(s.split(/\s+/).length + " words");

Now, put all of this in one line and add it as your keyword search. Try it!

(Note: You need to replace { curly braces } with %7B and %7D in Google Chrome. It interprets curly braces as a special command. Also, Chrome replaces spaces with a +, so the word count will always return 1 if you search for "count some set of words here".)

You could use selections to search as well. If you wanted to Google your selection, just use:

javascript:var s = "%s";
if (s == "it") {
  s = document.selection ? document.selection.createRange().text :
      window.getSelection ? window.getSelection().toString() : "";
}
location.replace("http://www.google.com/search?q=" + s)

Typing "google it" will search for your selected words on Google. "google some words" will search for "some words" on Google.

I’ve configured these keyword searches on my browser to:

  • Share sites. Typing "share google" adds the page to Google Reader, "share delicious" posts it to del.icio.us, "share digg" diggs the page, etc.
  • Send mail from the address bar. Typing "mail someone@gmail.com sub:This is the subject. Rest of the message" in the address bar will send the mail out. (Of course, you need to have created a mail gateway. I’ll try and share this shortly.)
  • Add entries to my calendar. Typing "remind Prepare dinner at 8pm" adds a reminder to my calendar to prepare dinner at 8pm.
  • Highlight parts of a page. Typing "highlight it" highlights what I’ve selected on the page. Even after I remove the selection, the highlighting stays. Typing "highlight some phrase" highlights all occurrences of "some phrase" in the entire document. The colours change every time you use it on a page, so you can search for multiple words and see where how they’re distributed.
  • Replaces tables with charts. Typing "chart it" with a table selected replaces the table with a chart. Typing "chart it as pie" or "chart it as scatter" changes the chart type.

You could actually take any bookmarklet and convert it into a keyword search. Which means that practically anything you can do on Javascript can be convert into a command-line-like syntax on the address bar.

So there it is! You can pretty much have a web command line. I wonder if we could add UNIX-pipes-like functionality.

Dynamically eliminate duplicates

This is a series on what Google Spreadsheets can do that Excel can’t

To get a list of unique values from a list, use the UNIQUE function on Google Spreadsheets.

For example, if you have a list of browsers in column A, type =UNIQUE(A1:A17) at cell B1 to get a unique list of browsers. This is a dynamic list. If you change the list of browsers, the unique list gets updated automatically.

1.1

You can use UNIQUE to create a dynamic pivot table. Quite often, you end up creating a pivot table simply to summarise by one column. The main purpose the pivot table serves is in getting a list of unique values on that column. Plus, it’s a bit heavy on the UI. And every time the data changes, you need to refresh the pivot. But with the UNIQUE function, you can get a dynamic list of unique values, and you can use the COUNTIF and SUMIF function next to each value. Here is an example showing the frequency table of the browsers shown earlier. Column C does a COUNTIF of the unique values on the original list.

1.2

You can also use UNIQUE as the input to another formula:

=COUNT(UNIQUE(LIST)) counts the number of unique values

=COUNT(LIST)-COUNT(UNIQUE(LIST)) gives the number of duplicates

=INDEX(UNIQUE(LIST),3) gives you the third unique value

=LARGE(UNIQUE(LIST),3) gives you the third largest unique value

… and so on.

Can I do that in Excel?

You can, but not easily. There are two approaches, but each has its limitations.

A. Use Advanced Filters: easy but static

  1. Create an advanced filter on column A (Alt-D-F-A)
  2. Select Copy to another location
  3. Click in the Copy to box, and then click the cell B1
  4. Select Unique records only
  5. Click OK

1.3

But the list of unique values that you get here is static. If you changed one of the values, the list of unique values does not change.

B. Use a complex formulae that are dynamic

First, blank out the duplicates by typing this formula:

=IF(COUNTIF(A$1:A1,A1)=1,A1,"")

adjacent to the first cell (into B1), and dragging it all the way down (to B17).

Now, create a named range (Alt-I-N-D) for these cells (B1:B17) called WithBlanks and another named range called NoBlanks for the cells one column to the right (C1:C17).

On the first cell of NoBlanks (C1), type this formula:

=IF(ROW()-ROW(NoBlanks)+1>ROWS(WithBlanks)-COUNTBLANK(WithBlanks),"",
    INDIRECT(ADDRESS(SMALL((IF(WithBlanks<>"",ROW(WithBlanks),ROW()+
    ROWS(WithBlanks))),ROW()-ROW(NoBlanks)+1),COLUMN(WithBlanks),4)))

Press Ctrl-Shift-Enter rather than Enter, because it’s an array formula. Now drag this all the way down (to C17).

The list in column C is dynamic. If you change a cell in column A, column C is updated. But the formula can only handle one column. Google Spreadsheets’ UNIQUE function works with any number of columns. If you had data in the range A1:D100 and wanted the unique rows, UNIQUE(A1:D100) gets that for you.

1.4

Note: I’m staying away from user defined functions. You could, of course, create a UNIQUE function in Excel using Visual Basic. In fact, you should!