See the attached for one way to go about this, using the following calculated fields:
# of Diff Products Bought by Customer: COUNTD([Product ID])
# of Customers: IF FIRST()==0 THEN WINDOW_COUNT(COUNTD([Customer ID])) END
In the view, put Customer ID on the Level of Detail Shelf. Then the # of Diff Products calc is brought onto the Rows Shelf, set to Discrete (a blue pill, so it will generate headers), and then click on the blue pill once more to uncheck Ignore in Table Calculations. Finally, the # of Customers can be put on the text shelf (or dragged over the Abc marks) to create a text table, and click on the green pill to set the Compute Using to Customer ID.
There are a couple of tricky bits in this kind of view: In order to have distinct counts of customers and products, both need to be in the overall level of detail (on Rows, Columns, Marks Card, or Pages Shelf) of the view, and in a view like this that's going to return overlapping results. So we use a table calculation with the IF FIRST()==0 to return only one result per partition. The next bit is that you are wanting to partition a measure (the customer count), i.e. generate headers, using the results of another aggregate measure (the count distinct of products per customer). Ordinarily Tableau will only partition based on non-aggregated dimensions. That's where the unchecking "Ignore in Table Calculations" comes in, it enables Tableau to partition by that calculation to generate the desired results.
Works like magic! Thanks very much