0

Starting with screenshot:

https://i.stack.imgur.com/p1Lzm.png

(I'm a new user, can't post images)

Working for a call center. We have a program that tracks our time spent in various phone states (so when we're on calls, out to lunch, etc) that can export data for a given team and date range as a CSV.

I'm working on automating this report. The way it works is that the team lead will pull the CSV, copy-paste into another tab, and then I've got a bunch of array formula If functions and Indirect references to pull all the data as shown. The data analysis and everything is working great.

My problem is the graph. Right now, I've got column B with an If function that either outputs the agent's email (which is how the system tracks it) or "" if all emails have been used. The rest of the columns have If(B2="","", [relevant formula]). That way, we can have all the team leads with various (and fluctuating) team sizes use the same report with a simple copy-paste.

My problem is the stupid bar chart. It pulls data from rows 2-32 (A2:A32). Our current largest team is 28, and I left room for new hires showing up soon. My problem happens when I use data from one of our smaller teams. As you can see, even though the blank rows are filled with "" in every cell, it's still displaying those rows. In the chart. This means that with the smallest team (shown), the chart is half wasted whitespace.

Is there a way to make the column chart only show rows that have actual data in them?

One thing I tried was putting an Indirect reference for Series Values. So I had a cell (AA1) with {=MAX(IF(B2:B31="","",ROW(B2:B31)))}. That outputs the row number of the last non-blank row. Then for the Series Values I put =Indirect("Report!A2:A"&AA1), but Excel gave me an error saying the function was not valid. I guess you can only have an actual range (and not a formula) in the data input for a chart.

Excel 2016, by the way.

Dacromir
  • 186
  • 2
  • 11
  • Are you willing to use VBA to dynamically build the chart? – OldUgly Nov 01 '16 at 21:15
  • Hiding the empty rows will (more correctly "can") omit them from the chart. Again, you will probably need VBA to auto hide/unhide rows. – OldUgly Nov 01 '16 at 21:25

2 Answers2

0

I come up with three possible solutions for this problem.

  1. Convert your data table to a pivot table and use a pivot chart (currently only available in Windows version, sorry if you are using a Mac).
  2. Use a bit of VBA to hide the empty rows.
  3. Use a bit of VBA to modify the data displayed on the chart.

Sample Data Setup

Although you provided a screen shot of your data, it is not simple to convert that into a test case to demonstrate the three solutions. Therefore, I threw together this very simple set up.

  1. Column A contains a list of possible "users".
  2. Cell D1 is a user entry to change the contents of column B and C.
  3. Column B contains the actual "users". It is calculated with =IF(A2<=$D$1,A2,"")
  4. Column C contains the data that goes with the "users". It is calculated with =IF(B2<>"",10,"")
  5. A chart is added to the sheet.

Below is a screenshot of the sample setup, where all potential users are included. (Note: It is Sheet1)

enter image description here

Below is a screenshot of the sample setup, where only potential users A through E are included.

enter image description here

The white space in the second image is the problem we are trying to address.

SOLUTION 1: Make a pivot table of the data

  1. Select all of the pertinent data, in this case B1:C12.
  2. Select Insert -> Pivot Table
  3. In the Create Pivot Table dialog, make sure "New Worksheet" is selected, and click OK.
  4. On the Pivot Table, place "User" field in Rows, and "Total" field in Values. Select the Value Field Settings... for the "Total" field and make sure it uses Sum.
  5. In the Pivot Table, select the Row Labels drop down, Label Filters, Greater Than... . Type "" into the dialog and select OK.
  6. From Pivot Table Tools -> Analyze, select PivotChart. Choose Bar Chart from the dialog.

Below is a screen shot of the Pivot Table.

enter image description here

On the tab with the data, change the last potential user from E to G. On the Pivot Table, refresh the data.

Below is a screen shot of the refreshed pivot table.

enter image description here

SOLUTION 2: Use VBA to hide empty rows

The below code is attached to a button made visible on the worksheet. (n.b. There are other ways to activate the code such as change events, but this will depend on a number of factors outside the scope of this answer).

Sub HideRows()

Dim AllCatRange As Range
Set AllCatRange = Worksheets("Sheet1").Range("B2:B12")

Dim iLoop As Long
For iLoop = 1 To AllCatRange.Rows.Count
    If AllCatRange.Cells(iLoop, 1) = "" Then
        AllCatRange.Cells(iLoop, 1).EntireRow.Hidden = True
    Else
        AllCatRange.Cells(iLoop, 1).EntireRow.Hidden = False
    End If
Next iLoop

Set AllCatRange = Nothing

End Sub

Below is a screen shot of the data tab with the button added.

enter image description here

After clicking the button, it now looks like this ...

enter image description here

This code will expand rows when they contain data, and collapse rows when they do not.

A potential problem with this approach is that expanding/collapsing rows will change the size of the chart, if the chart lays over those rows.

SOLUTION 3: Use VBA to modify the chart

The below code is attached to a button, and used to modify the chart after the source data is changed.

Sub ModifyChart()
Dim AllCatRange As Range
Set AllCatRange = Worksheets("Sheet1").Range("B2:B12")

Dim lastRow As Long
lastRow = 1

Dim iLoop As Long
For iLoop = 1 To 11
    If AllCatRange.Cells(iLoop, 1) <> "" Then
        lastRow = lastRow + 1
    End If
Next iLoop

Dim PlotCatRange As Range
Set PlotCatRange = Worksheets("Sheet1").Range("B2:B" & lastRow)

Dim PlotSerRange As Range
Set PlotSerRange = Worksheets("Sheet1").Range("C2:C" & lastRow)

Worksheets("Sheet1").ChartObjects(1).Chart.FullSeriesCollection(1).XValues = "=Sheet1!" & PlotCatRange.Address
Worksheets("Sheet1").ChartObjects(1).Chart.FullSeriesCollection(1).Values = "=Sheet1!" & PlotSerRange.Address

Set AllCatRange = Nothing
Set PlotCatRange = Nothing
Set PlotSerRange = Nothing

End Sub

Below is a screenshot of the data tab with the new button in place.

enter image description here

Below is a screenshot of the tab after clicking the button.

enter image description here

Wrap up

My personal preference is to use VBA to modify the chart after the data is modified, as this reflects what you would do manually.

OldUgly
  • 2,129
  • 3
  • 13
  • 21
0

I found a solution! Thanks largely to this page. Here's what I did:

I created made a named range using this formula: =OFFSET(Report!$B$1,1,0,COUNTIF(Report!$B$2:$B$30,"<>-"),1)

For that to work, I had to change all the empty cells to output "-" when empty in stead of "". I couldn't get COUNTIF to accept "<>""" or "<>" or any other weird tricks I tried. Using "-" was easier.

That makes a dynamic named range that changes size as I put data into the sheet. I named a similar range for everything I'm trying to chart (Approved Status, Call Ready, Not Ready). The chart was able to accept those names and now it's dynamically sized. If I only have three agents on the sheet, it shows three huge bars. With twenty, it shows twenty bars (exactly what I was looking for).

One other tip: I changed my first row to output "" when empty, so that COUNTIF(Report!$B$2:$B$30,"<>-") always returns at least 1 (otherwise you get annoying errors because you have a named range referencing a 0-length array).

Dacromir
  • 186
  • 2
  • 11