35

Is it possible to get a range with PHP from A to ZZ*?

a b c ... aa ... zx zy zz

For me this didn't work:

range('A', 'ZZ');

It's for PHPExcel, when it gives BE as highest field i'd run through all colums. In this case i only get A, B:

range ('A', 'BE')
Ronn0
  • 2,249
  • 2
  • 21
  • 36

17 Answers17

68

Take advantage of PHP's ability to increment characters "perl-style"

$letters = array();
$letter = 'A';
while ($letter !== 'AAA') {
    $letters[] = $letter++;
}

But you could also use simple integer values, and take advantage of PHPExcel's built-in PHPExcel_Cell::stringFromColumnIndex() method

EDIT

From PHP 5.5, you can also use Generators to avoid actually building the array in memory

function excelColumnRange($lower, $upper) {
    ++$upper;
    for ($i = $lower; $i !== $upper; ++$i) {
        yield $i;
    }
}

foreach (excelColumnRange('A', 'ZZ') as $value) {
    echo $value, PHP_EOL;
}
Mark Baker
  • 209,507
  • 32
  • 346
  • 385
  • Interesting approach! I never knew you could do something weird like incrementing strings, but this seems to work perfectly :) – Oldskool Jan 11 '13 at 13:06
  • 1
    Main gotcha for the end condition in the loop is "don't use > or <", always use !==; but it's a very useful feature. Unfortunately you can't use the -- decrementor – Mark Baker Jan 11 '13 at 13:08
  • @MarkBaker Do you know the reason why we can't use decrement operator? And why "don't use at loop > or <"? – Viacheslav Kondratiuk Jan 11 '13 at 19:23
  • Decrementor simply isn't coded for alpha, but don't know why it never was. Why not > or Try using < 'AAA' instead of !== 'AAA' – Mark Baker Jan 11 '13 at 23:29
  • Thinking about it, I suspect the decrement operator isn't implemented for characters because of what should happen when you decrement 'A' or 'a'.... it can't be handled as simply as a numeric decrementor – Mark Baker Jan 14 '13 at 09:55
  • This doesn't appear to be working any longer - at least not for me on php 5.5 – Jacob Thomason Dec 27 '13 at 07:44
  • This code still works in exactly the same way in PHP >= 5.5, though you can also take advantage of new features such as Generators in PHP 5.5 – Mark Baker Dec 27 '13 at 11:04
  • https://phpspreadsheet.readthedocs.io/en/latest/ – CrandellWS Nov 25 '21 at 23:37
18

Just Try this- (tested working fine)

function createColumnsArray($end_column, $first_letters = '')
{
  $columns = array();
  $length = strlen($end_column);
  $letters = range('A', 'Z');

  // Iterate over 26 letters.
  foreach ($letters as $letter) {
      // Paste the $first_letters before the next.
      $column = $first_letters . $letter;

      // Add the column to the final array.
      $columns[] = $column;

      // If it was the end column that was added, return the columns.
      if ($column == $end_column)
          return $columns;
  }

  // Add the column children.
  foreach ($columns as $column) {
      // Don't itterate if the $end_column was already set in a previous itteration.
      // Stop iterating if you've reached the maximum character length.
      if (!in_array($end_column, $columns) && strlen($column) < $length) {
          $new_columns = createColumnsArray($end_column, $column);
          // Merge the new columns which were created with the final columns array.
          $columns = array_merge($columns, $new_columns);
      }
  }

  return $columns;
}
echo "<pre>";
print_r( createColumnsArray('BZ'));

copied from http://php.net/range

Suresh Kamrushi
  • 15,627
  • 13
  • 75
  • 90
16
for ($i = 'A'; $i !== 'AC'; $i++){
    echo $i.', '; //A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, AA, AB,
}

it's working

Gottlieb Notschnabel
  • 9,408
  • 18
  • 74
  • 116
Donot Don't
  • 609
  • 7
  • 12
8

You can combine two foreach loops to generate something like that.

// Single letters
foreach(range('A', 'Z') as $letter) {
    echo $letter;
}

// AA-ZZ combinations
foreach(range('A', 'Z') as $letter1) {
    foreach(range('A', 'Z') as $letter2) {
        echo $letter1 . $letter2;
    }
}
Oldskool
  • 34,211
  • 7
  • 53
  • 66
2

It's not possible with the built-in range:

Support for character sequences and decrementing arrays was added in 4.1.0. Character sequence values are limited to a length of one. If a length greater than one is entered, only the first character is used.

However, in essence what you are doing here is counting upwards from 1 in a numeric system that uses the 26 digits a to z. So you can quickly hack together a solution by counting, converting to base 26 (which uses the digits 0 to 9 and a to p) and then "translating" the digits to the range a to z.

Jon
  • 428,835
  • 81
  • 738
  • 806
2

Even better option (Working great)

for ($i = 'a'; $i < 'zz'; $i++) 
    echo $i."<br>";
Suresh Kamrushi
  • 15,627
  • 13
  • 75
  • 90
1

You could ofcourse write your own function to do this as it seems that the range() function in php doesn't support this. This should be an easy job, since you can just nest the range function in another loop. Something like this:

foreach(range('a', 'z') as $outer) {
  foreach(range('a', 'z') as $inner) {
    print($outer.$inner);
  }
}
Ignacio
  • 7,947
  • 15
  • 63
  • 74
Tarilo
  • 430
  • 2
  • 6
1

Please check this simple solution incrementing char.

How to list from A to Z in PHP, and then on to AA, AB, AC, etc

Use this recursive function to get the exact range from A to ZZ

function myRange($end_column = '', $first_letters = '') {
    $columns = array();
    $length = strlen($end_column);
    $letters = range('A', 'Z');

    // Iterate over 26 letters.
    foreach ($letters as $letter) {
      // Paste the $first_letters before the next.
      $column = $first_letters . $letter; 
      // Add the column to the final array.
      $columns[] = $column;
      // If it was the end column that was added, return the columns.
      if ($column == $end_column)
          return $columns;
    }

    // Add the column children.
    foreach ($columns as $column) {
      // Don't itterate if the $end_column was already set in a previous itteration.
      // Stop iterating if you've reached the maximum character length.
      if (!in_array($end_column, $columns) && strlen($column) < $length) {
          $new_columns = myRange($end_column, $column);
          // Merge the new columns which were created with the final columns array.
          $columns = array_merge($columns, $new_columns);
      }
    }

    return $columns;
}

call function like.

print_r(myRange('ZZ'));

will give you result

A B C . . . ZX ZY ZZ

Shailesh Sonare
  • 2,791
  • 1
  • 18
  • 14
0

Here is a simplified solution in which you can define number of rows and columns you want to generate. This way you will allocate lesser memory.

// Get cell names for excel
function generate_excel_cell_names($row_cnt, $col_cnt){
    $excel_cells = [];

    // Note: Row and col indexes are starting from 1
    for ($excel_row=1; $excel_row <= $row_cnt; $excel_row++) { 
        $excel_col = 'A';
        for ($col_index = 1; $col_index <= $col_cnt; $col_index++)
        {
            $excel_cells[$excel_row][$col_index] = $excel_col.$excel_row;
            $excel_col++;
        }
    }
    return $excel_cells;
}
Mayur Chauhan
  • 682
  • 1
  • 12
  • 25
0

This works well for me.

function create_columns_range($start = 'A', $end = 'ZZ'){
    $return_range = [];
    for ($i = $start; $i !== $end; $i++){
        $return_range[] = $i;
    }
    return $return_range;
}

To use it just call:

$range = create_columns_range('A', 'ZZ');
print_r(range);
Mohamad Hamouday
  • 2,070
  • 23
  • 20
0

If you don't know to which letter you have to get, but you do know the length:

$max = 200; 
for ($l = 'A', $i = 0; $i < $max; $l++, $i++) {
    $letters[] = $l;
}
echo $letters; 
Aldo
  • 730
  • 8
  • 20
0
    $arr = [];
    foreach (range('A', 'Z') as $alphabeta) {
        $arr[] = $alphabeta;
    }
    foreach ($arr as $key => $val) {
        foreach (range('A', 'Z') as $alphabetb) {
            $arr[] = $arr[$key] . $alphabetb;
        }
    }
    print_r($arr);
  • 1
    Can you elaborate on what your code does and how is answers the question? don't simply post a code. – stramin Feb 24 '23 at 16:02
  • While this code snippet may be the solution, including a detailed explanation really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion. – Shawn Hemelstrand Feb 26 '23 at 01:41
-1

This is as far as I can help you (generate array with A through Z).

$a = range(65, 90);
array_walk($a, 'chr');

Check out chr and array_walk

Vlad Preda
  • 9,780
  • 7
  • 36
  • 63
  • OP's need was to get into 'AA', 'AB' , ... after Z. Moreover, your code is strictly equivalent to $a = range('A', 'Z'). Which is simpler and clearer. – Pierre-Olivier Vares Jul 28 '21 at 15:03
-1

I use alpha2num() to convert alpha to number and then use it in loop. With this I can get the range using any value for the start and end.

// to convert alpha to number
function alpha2num($a) {
    $l = strlen($a);
    $n = 0;
    for($i = 0; $i < $l; $i++)
        $n = $n*26 + ord($a[$i]) - 0x40;

    return $n-1;
}

// to convert number back to alpha
function num2alpha($n)
{
    for($r = ""; $n >= 0; $n = intval($n / 26) - 1)
    $r = chr($n%26 + 0x41) . $r;
    return $r;
}

function get_range($start_column, $end_column)
{
    $s = alpha2num($start_column); // get start number
    $e = alpha2num($end_column); // get end num

    $columns = array();

    // loop from start to end and change back the number to alpha to be stored in array
    for($i=$s; $i<=$e; $i++)
        $columns[] = num2alpha($i);

    return $columns;
}

// usage
$columns = get_range('Z', 'BA'));
Zan Asmon
  • 1
  • 2
-1
$atoz = range('A', 'Z');
$target = range('A', 'Z');

$result = $atoz;
foreach ($target as $val) {
    $step = array_map(function ($elem) use ($val) {
            return $val. $elem;
        }, $atoz);

    $result = array_merge($result, $step);
}
JaeHun
  • 1
  • 1
-1
$abc = [];
foreach(range('A', 'Z') as $first) {
    array_push($abc, $first);
}

foreach(range('A', 'Z') as $second) {
  foreach(range('A', 'Z') as $third) {      
      array_push($abc, $second.$third);
  }
}

$headers = ['CAMPO', 'CAMPO', 'CAMPO', 'CAMPO', 'CAMPO', 'CAMPO', 'CAMPO', 'CAMPO', 'CAMPO', 'CAMPO', 'CAMPO', 'CAMPO', 'CAMPO', 'CAMPO', 'CAMPO', 'CAMPO', 'CAMPO', 'CAMPO', 'CAMPO', 'CAMPO', 'CAMPO', 'CAMPO', 'CAMPO', 'CAMPO', 'CAMPO', 'CAMPO', 'CAMPO', 'CAMPO', 'CAMPO'];

foreach($headers as $key => $value) {
  echo $abc[$key] . ' - ' . $value . PHP_EOL;
}
  • This is essentially the same as [this existing answer](https://stackoverflow.com/a/14278751/4205384). – El_Vanja Apr 30 '21 at 22:28
-1
$alfabet=["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","AA","AB","AC","AD","AE","AF","AG","AH","AI","AJ","AK","AL","AM","AN","AO","AP","AQ","AR","AS","AT","AU","AV","AW","AX","AY","AZ","BA","BB","BC","BD","BE","BF","BG","BH","BI","BJ","BK","BL","BM","BN","BO","BP","BQ","BR","BS","BT","BU","BV","BW","BX","BY","BZ","CA","CB","CC","CD","CE","CF","CG","CH","CI","CJ","CK","CL","CM","CN","CO","CP","CQ","CR","CS","CT","CU","CV","CW","CX","CY","CZ","DA","DB","DD","DD","DE","DF","DG","DH","DI","DJ","DK","DL","DM","DN","DO","DP","DQ","DR","DS","DT","DU","DV","DW","DX","DY","DZ"];

 $active_row_value_fulladdress = "AA - AM";
 //$active_row_value_fulladdress = "A - F";
 $taken_full = strtoupper($active_row_value_fulladdress);

$taken_full_ar = explode("-", $taken_full);
$start = trim($taken_full_ar[0]);
$end   = trim($taken_full_ar[1]);

$alfabet_key = array_flip($alfabet);
$start1 = $alfabet_key[$start];
$end1   = $alfabet_key[$end];

for($i=$start1;$i<=$end1;$i++)
{
    $taken_full_array[]=$alfabet[$i];
}

foreach ($taken_full_array as $key => $value) 
{
    $full_add[]=array_search($value,$alfabet);
}

echo "<pre>";
print_r($taken_full_array);
print_r($full_add);
Zahid Gani
  • 169
  • 6