REPT Function: Create In‑Cell Charts, Progress Bars & Visual Effects

REPT Function in Excel Tutorial Blog Feature Image
Excel’s REPT function repeats any character a specified number of times — making it the simplest way to build in-cell bar charts, progress bars, and star ratings without chart objects or conditional formatting data bars. Unlike data bars, REPT output is plain text that recalculates faster, stays stable when copied, and can change color based on custom threshold rules via conditional formatting. This guide covers the syntax, the best Unicode characters to use, and 8 practical examples including scaled bar charts, filled-and-empty progress bars, star ratings, tally marks, and the classic “z×255” trick for finding the last text entry in a list.

Excel's conditional formatting data bars look professional but carry a hidden cost. They slow down large workbooks, create "rule rot" when copied across sheets, and offer no way to change colours based on custom conditions. The REPT function solves all three problems at once. It repeats any character a specified number of times, producing a lightweight text string that behaves exactly like a visual bar. Consequently, it is faster, simpler to maintain, and fully compatible with conditional formatting rules that change colour based on your own logic.

Beyond progress bars, REPT also creates star ratings, dot plots, text padding, tally marks, and self-updating dashboard labels — all from a single two-argument function.

Availability: REPT works in every Excel version from Excel 2000 onwards, including Microsoft 365, Excel 2024, 2021, 2019, and 2016. It also works in Google Sheets with identical syntax.

What Is the REPT Syntax?

REPT takes just two arguments — what to repeat and how many times.

=REPT(text, number_times)
ArgumentRequired?What it does
textRequiredThe character or string to repeat. Can be any text — a single character like "|", a Unicode symbol inserted with UNICHAR(), or a text string like "AB".
number_timesRequiredHow many times to repeat the text. If this is a decimal, it is truncated to an integer (not rounded). If it is 0, REPT returns an empty string. The total result cannot exceed 32,767 characters.
REPT truncates decimals — use ROUND() for accurate bars: If number_times is 7.9, REPT produces 7 repetitions, not 8. For progress bars driven by percentages, always wrap the calculation in ROUND() to get the nearest whole number: =REPT("█", ROUND(B2*20, 0)).

Which Characters Work Best?

The visual quality of an in-cell chart depends entirely on which character you choose. Some characters produce solid-looking bars. Others create rating symbols or dot plots. The table below lists the most useful options along with the UNICHAR code to insert each one.

CharacterCodeBest for
|CHAR(124)Thin bars — classic style, available on every keyboard. Use Playbill or Britannic Bold font to merge them into a solid bar.
UNICHAR(9608)Solid block bars — the most visually convincing bar character. No special font required.
UNICHAR(9617)Empty/remaining segment — pair with █ to show filled vs unfilled portions of a progress bar.
UNICHAR(9679)Filled dot — modern dot plot style. Clean and readable at small sizes.
UNICHAR(9675)Empty dot — pair with ● for a dot-based progress indicator.
UNICHAR(9733)Filled star — ideal for 1–5 or 1–10 star ratings.
UNICHAR(9734)Empty star — pair with ★ to show unfilled rating positions.
UNICHAR(9670)Diamond — compact alternative to stars for rating scales.

Example 1: Simple In-Cell Bar Chart

The most fundamental use is mapping a numeric value directly to a bar length. REPT repeats the bar character as many times as the value. The result is a proportional visual bar that updates automatically when the source data changes.

1
Bar chart from raw values — repeating | to match a number
A — Name
B — Score
C — Bar
Sarah
8
||||||||
James
5
|||||
Priya
10
||||||||||
Score 1–10 in column B. Enter in C2 and copy down. The "|" character repeats as many times as the score value. =REPT("|", B2) For a solid bar appearance — change the cell font to Playbill or Britannic Bold. These fonts compress the "|" characters into a continuous solid bar with no gaps. Block character version — no special font needed, more solid appearance: =REPT("█", B2) → ████████ (for a score of 8)
Font choice matters for pipe-character bars: The "|" character has gaps between repetitions in most standard fonts. Changing the cell font to Playbill, Britannic Bold, or Stencil merges the characters into a solid, seamless bar. No special font is required when using the █ block character.

Example 2: Scaled Bar — Normalise Any Range to a Fixed Width

Raw values are rarely between 1 and 50 — the natural bar width. Scaling normalises any value range into a fixed bar length. Dividing each value by the maximum and multiplying by the target width (typically 20 or 30 characters) produces proportional bars regardless of the data range.

2
Scaled bar — sales values from £0 to £50,000 mapped to 20-character width
A — Region
B — Sales
C — Bar (width 20)
East
£48,500
███████████████████░
North
£24,000
█████████░░░░░░░░░░░
West
£50,000
████████████████████
Scale each value to a 20-character bar using the column maximum. MAX($B$2:$B$100) finds the largest value. Dividing by it normalises to 0–1. Multiplying by 20 maps to 0–20. ROUND prevents truncation errors. =REPT("█", ROUND(B2 / MAX($B$2:$B$100) * 20, 0)) Show the value alongside the bar — append it with the ampersand: TEXT formats the number as currency for a cleaner label. =REPT("█", ROUND(B2/MAX($B$2:$B$100)*20, 0)) & " " & TEXT(B2,"£#,##0") → ████████████ £48,500

Example 3: Filled and Empty Progress Bar for Percentages

Combining two REPT calls — one for the filled portion and one for the remaining portion — creates a progress bar with a clear visual boundary. The filled segment grows as the percentage increases. The empty segment shrinks proportionally. Adding a percentage label at the end makes the bar fully self-documenting.

3
Two-part progress bar — filled █ + empty ░ + percentage label
A — Task
B — % Done
C — Progress bar
Design
100%
████████████████████ 100%
Dev
75%
███████████████░░░░░ 75%
Testing
30%
██████░░░░░░░░░░░░░░ 30%
B2 holds a decimal like 0.75 (75%). Total bar width = 20 characters. ROUND(B2*20, 0) = filled segments. 20 - ROUND(B2*20, 0) = remaining empty segments. TEXT(B2, "0%") appends the percentage label. =REPT("█", ROUND(B2*20, 0)) & =REPT("░", 20-ROUND(B2*20, 0)) & " " & TEXT(B2, "0%") → ███████████████░░░░░ 75% (for 75%) Dot style version — same pattern with ● and ○: ●●●●●●●●●●○○○○○○○○○○ 50% =REPT("●", ROUND(B2*10, 0)) & =REPT("○", 10-ROUND(B2*10, 0)) & " " & TEXT(B2, "0%")

Example 4: Star Rating Display

Star ratings are one of the most visually recognisable data formats. REPT reproduces them natively — filled stars for the achieved rating and empty stars for the remaining positions. The pattern works for any scale: 1–5, 1–10, or any other range.

4
Star rating — filled ★ and empty ☆ for a 1–5 scale
A — Product
B — Rating
C — Stars
Widget Pro
5
★★★★★
Gadget X
3
★★★☆☆
Basic Kit
1
★☆☆☆☆
B2 holds the rating (1–5). Maximum scale is 5. Filled stars = rating. Empty stars = 5 minus the rating. The ★ character is UNICHAR(9733), ☆ is UNICHAR(9734). =REPT("★", B2) & =REPT("☆", 5-B2) → ★★★☆☆ (for a rating of 3) Using UNICHAR() — safer than copy-pasting symbols directly into formulas: UNICHAR(9733) = ★ (filled star) UNICHAR(9734) = ☆ (empty star) =REPT(UNICHAR(9733), B2) & =REPT(UNICHAR(9734), 5-B2) Diamond version (♦) for a more compact rating scale: UNICHAR(9670) = ♦ UNICHAR(9671) = ◇ =REPT(UNICHAR(9670), B2) & =REPT(UNICHAR(9671), 5-B2) → ♦♦♦◇◇ (for a rating of 3)

Example 5: Conditional Bar with Colour — REPT + Conditional Formatting

REPT produces text, and conditional formatting applies colour to text. Together they produce traffic-light bars — green for on-target values, amber for warning, red for critical. This combination is specifically what REPT achieves that standard data bars cannot: rule-based colour logic tied to actual thresholds rather than gradient shading.

5
Traffic-light bar — green above 75%, amber 50–75%, red below 50%
Step 1 — Create the scaled bar in column C (20-char width, percentage input): B2 holds a decimal like 0.75 (75%). =REPT("█", ROUND(B2*20, 0)) Step 2 — Apply conditional formatting to the bar column (C2:C100). Use "Format cells based on a formula" and reference the source column (B). Each rule changes the font colour of the bar text: Rule 1 — GREEN: Apply this formula to format when value is at or above target. The formula checks column B (the source percentage), not column C. =B2 >= 0.75 → font colour: Green Rule 2 — AMBER: Apply this formula for the warning range. =AND(B2 >= 0.5, B2 < 0.75) → font colour: Amber Rule 3 — RED: Apply this formula for below-threshold values. =B2 < 0.5 → font colour: Red The REPT bar itself stays identical in all three rules. Only the font colour changes — driven entirely by the value in column B. Tip — set the rule priority correctly: Green rule should be first, red rule last, so they do not override each other.
This is the core advantage of REPT over built-in data bars. Standard data bars apply a gradient and cannot change colour based on threshold logic. REPT bars are text — so any conditional formatting rule that targets the bar cell can set the font colour to any value, driven by any formula, with full control over the thresholds.

Example 6: Text Padding for Aligned Output

REPT with spaces is useful for right-aligning labels in monospaced-font columns or for adding visual spacing in dashboard rows. Padding each label to a fixed total width ensures columns stay aligned even when the source strings have different lengths.

6
Pad text to a fixed width — right-align labels using REPT spaces
Pad the label in A2 to exactly 20 characters using trailing spaces. LEN(A2) gives the current length. 20 - LEN(A2) is how many spaces to add. REPT(" ", ...) creates that many space characters. =REPT(" ", 20-LEN(A2)) & A2 → " East Region" (padded to 20 chars, right-aligned) Left-pad with dots instead of spaces — useful for menu-style layouts: =REPT(".", 20-LEN(A2)) & A2 → "...........East Region" Add minimum row height in a table — REPT line breaks for row spacing: CHAR(10) creates a line break. Repeating it twice adds blank lines below each row. Enable Wrap Text on the column for this to take effect. =REPT(CHAR(10), 2) ← place in a "Spacing" column; set it to white text to hide the content

Example 7: Tally Chart and Repeat Counter

REPT makes excellent tally marks for counts and frequency displays. Repeating a mark character by a count value produces a visual tally that is instantly readable. This is particularly useful for count data in dashboards where space is limited and a full chart is unnecessary.

7
Tally marks and frequency charts — repeat a mark symbol by a count
A — Category
B — Count
C — Tally
Bugs reported
7
●●●●●●●
Bugs fixed
12
●●●●●●●●●●●●
Basic tally using dot character: =REPT("●", B2) Classic tally marks (groups of 5) using a text pattern approach: Show groups of four marks plus a crossing mark for each complete group of 5. INT(B2/5) = complete groups, MOD(B2,5) = remaining marks. For 7 counts: 1 complete group (||||) + 2 remaining = ||||| || =REPT("| | | | | ", INT(B2/5)) & =REPT("|", MOD(B2, 5)) → "| | | | | | |" (for a count of 7) Conditional count display — show "Yes" repeated by COUNTIF result: Count how many times "East" appears, then show that many check marks. =REPT("✓", COUNTIF(A:A, "East"))

Example 8: REPT Without MATCH — Find the Last Text Entry

REPT has a useful edge-case trick that goes beyond visual effects. By repeating "z" 255 times, you create a text string that sorts to the absolute end of any alphabetical list. VLOOKUP with approximate match then finds the last text entry in a column. This pattern is a classic workaround for locating the final non-blank text value.

8
Find the last text entry in a column — REPT("z", 255) lookup trick
Column A contains a mixed list of text entries and blanks. REPT("z", 255) creates "zzzzz..." — a string that sorts after any real word. VLOOKUP with match_type 1 (approximate) finds the last text entry before this string. =VLOOKUP(=REPT("z", 255), A:A, 1, 1) → Returns the last text value in column A Alternative using LOOKUP — often more reliable across versions: LOOKUP("zzz", A2:A100) finds the last text entry without approximate-match dependency. =LOOKUP(=REPT("z", 255), A2:A100) → Returns the last non-blank text value in A2:A100 Note: this trick works for TEXT entries only. For numeric last-value searches, use LOOKUP(9^9, ...) instead.
Why "z" repeated 255 times? Text values sort alphabetically in Excel. A string of 255 "z" characters sorts after every real word because no genuine dictionary word matches that pattern. VLOOKUP approximate match consequently falls back to the last real text entry — which is exactly what you want.

Common REPT Issues and How to Fix Them

Bar shows fewer segments than expected

REPT truncates decimal values without rounding. If number_times is 7.9, the bar shows 7 segments, not 8. Wrap the calculation in ROUND(): =REPT("█", ROUND(B2*20, 0)). This ensures you get the nearest whole number of segments rather than the truncated value.

Bar looks gapped or uneven in pipe-character style

The "|" character has natural whitespace around it in most standard fonts. Consequently, repeated pipes do not form a solid bar — they appear as separate strokes with gaps. Fix this by changing the cell font to Playbill, Britannic Bold, or Stencil. Alternatively, switch to the solid block character (█) which needs no special font.

#VALUE! error

REPT returns #VALUE! when number_times is negative or when the total result would exceed 32,767 characters. Check that the value driving the repeat count cannot go negative. Additionally, for large datasets, confirm that the scale multiplier does not produce a character count above 32,767 for any single row.

REPT bars are text — they cannot be sorted numerically: The bar column contains text strings, not numbers. Sorting by the bar column will sort alphabetically by character count, not by the underlying value. Always sort by the source data column (column B) rather than the REPT bar column.

Frequently Asked Questions

  • What does the REPT function do in Excel?+
    REPT repeats a text string a specified number of times. The syntax is =REPT(text, number_times). For example, =REPT("█", 10) returns "██████████" — ten solid block characters. This makes it ideal for creating in-cell bar charts, progress bars, star ratings, tally marks, and text padding — all without any chart objects or complex conditional formatting.
  • Why does my REPT bar show fewer segments than I expect?+
    REPT truncates decimal values instead of rounding them. If number_times evaluates to 7.9, REPT produces 7 segments — not 8. The fix is to wrap the calculation in ROUND(): =REPT("█", ROUND(B2*20, 0)). This converts the calculated length to the nearest whole number before REPT uses it, giving you the expected segment count.
  • How do I make REPT bars change colour based on the value?+
    Apply conditional formatting to the REPT bar column using the "Format cells based on a formula" rule type. Reference the source value column (not the bar column) in the formula. For example, to make bars green when the source is above 75%, set the rule formula to =B2>=0.75 and apply a green font colour. Add additional rules for amber and red thresholds. The bar character stays the same — only the font colour changes. This is precisely the behaviour that standard data bars cannot replicate.

More Questions About REPT

  • What is the best character to use for REPT progress bars?+
    The solid block character █ (UNICHAR(9608)) is the most visually solid choice — it produces a seamless filled bar without requiring a special font. For a two-part bar that shows filled and remaining segments, pair it with the light shade character ░ (UNICHAR(9617)). The pipe character | is a classic alternative, but it needs a font like Playbill or Britannic Bold to eliminate the gaps between repetitions.
  • Is REPT faster than conditional formatting data bars?+
    Yes. Excel treats REPT output as plain text, which is significantly lighter than graphical conditional formatting rules. Data bars require Excel to render a gradient graphic in each cell and recalculate whenever source data changes. REPT bars are just text strings — they recalculate with the normal formula engine and produce no rendering overhead. In workbooks with thousands of rows, switching from data bars to REPT can noticeably reduce file size and recalculation time.
  • Which Excel versions support REPT?+
    REPT is available in every Excel version from Excel 2000 onwards, including Microsoft 365, Excel 2024, 2021, 2019, and 2016. It also works identically in Google Sheets. UNICHAR(), used for inserting Unicode characters like █ and ★ into REPT formulas, is available in Excel 2013 and later. For Excel 2010 and earlier, copy-paste the Unicode character directly into the formula string instead of using UNICHAR().