2

Excel スプレッドシートで作業していますが、大量のデータに対して 1 種類の数式のみを使用する必要があります。数式で必要な変更は文字に関するものだけなので、Excel の列の順序 (A、B、C...Z; AA、AB、AC...) に従ってインクリメントするプログラムを作成する方法があるかどうか疑問に思っていました。 AZ; BA、BB、BC...BZ)。

私の場合、毎回文字を 5 ずつインクリメントする必要があるため、取得しようとしているコードの種類は次のとおりです。

#include <iostream>

using namespace std;

int main() {

 char x = 'B';
 char y = 'E';
 for (int z = 1; z < 2255; z++) {
   cout << "=SUMPRODUCT(SUBTOTAL(4,OFFSET(" << x << "1:" << y << "1,ROW(" << x << "1:" << x << "100)-ROW(" << x << "1),)))" << endl;
   x = x + 5;
   y= y + 5;
  }
  return 0;
}

もちろん、「z」を超えるのでうまくいきませんが、それでもこれを行う方法はありますか?

4

5 に答える 5

1

一般的なソリューションの説明

解決策 1: base-26 システム自体を作成します。

26文字あるとします。ということで、まずは26数体系を作ってみましょう。各桁に 1 バイトを使用します。数字の配列を作成し、加算が 26 を超える場合は調整する必要があります。

あなたの現在の桁が 25 であると仮定しましょう。それに 7 を追加します。次に、256 (1 バイト) を最大としてオーバーフローを処理する必要があり、桁の制限は 26 です。したがって、調整は になります 256-26=230。(この計算は short (16 ビット) で行うため、 でオーバーフローし26+7=33 -> 33+230=263ます。したがって、上位バイトは 1、下位バイトは 7 になります。)

オーバーフローのしきい値を計算したら (上記は 1 でした)、次の桁にそれを追加し、オーバーフローが発生した場合に同じことを行うことができます。

最後に、表示のために、2 バイトのそれぞれに 65 ('A') を追加するだけです。最後のバイトは '\0' null で終了するため、文字列に変換できます。

解決策 2すべての計算を実行してから、26 進数に変換します。

この場合、

number/26 = x

remainder r1 = (number%26)

r1 をバイトに格納します。

x/26 = x1

remainder r2 = (x%26)

r2 を次のバイトに格納します。

x1/26 = x2

remainder r3 = (x%26)

r3 を次のバイトに格納します。文字列を取得し、r3 r2 r1 '\0'各バイトに 65 個の「A」を追加します。

于 2013-06-27T05:06:54.873 に答える
0

1 つのオプションとして、2 つの文字で構成される新しいデータ型を作成することができます (std::pair<char,char>このような演算を定義します。

ただし、カウントと算術演算にint(または) を使用し続け、整数を Excel の 1 文字または 2 文字の列見出しに変換する関数を定義する方が簡単だと思います。unsigned intto_col_heading

#include <string>
#include <iostream>
#include <stdexcept>
#include <iterator>

/* This is the function that performs
   the transformation. */    
std::string to_col_heading(unsigned i)
{
  if (i > 26+26*26)
    throw std::overflow_error
      ("Value too large for transformation into Excel column heading.");

  char char1 = 'A' + (i / 26) - 1;
  char char2 = 'A' + (i % 26);

  if (char1 < 'A')
    return std::string(&char2,&char2 + 1);
  else
    return std::string(&char1,&char1 + 1) + char2;
}

int main()
{
  std::ostream_iterator<std::string> out(std::cout,", ");
  for (unsigned i = 0 ; i < 26+26*26 ; i += 5)
    *out = to_col_heading(i);

  std::cout << std::endl;
  return 0;
}

出力:

A, F, K, P, U, Z, AE, AJ, AO, AT, AY, BD, BI, BN, BS, BX, CC, CH, CM, CR, CW, DB, DG, DL, DQ, DV, EA, EF, EK, EP, EU, EZ, FE, FJ, FO, FT, FY, GD, GI, GN, GS, GX, HC, HH, HM, HR, HW, IB, IG, IL, IQ, IV, JA, JF, JK, JP, JU, JZ, KE, KJ, KO, KT, KY, LD, LI, LN, LS, LX, MC, MH, MM, MR, MW, NB, NG, NL, NQ, NV, OA, OF, OK, OP, OU, OZ, PE, PJ, PO, PT, PY, QD, QI, QN, QS, QX, RC, RH, RM, RR, RW, SB, SG, SL, SQ, SV, TA, TF, TK, TP, TU, TZ, UE, UJ, UO, UT, UY, VD, VI, VN, VS, VX, WC, WH, WM, WR, WW, XB, XG, XL, XQ, XV, YA, YF, YK, YP, YU, YZ, ZE, ZJ, ZO, ZT, ZY,

列見出しに最大 3 桁 (アルファベット) をサポートするには、以下の関数が機能します。最初の 26 個の値を完全に個別に処理して、残りの計算を簡素化します。また、26 の累乗をより一貫した方法で処理するために、いくつかの静的定数を導入しました。3 桁の場合、26 0、26 1および 26 2が必要ですが、システムは任意の桁数をカバーするように拡張できます。

これを速度のために最適化する方法があると確信しています。これはここでは焦点ではありませんでした。

std::string to_col_heading(unsigned i)
{
  const static unsigned pow1 = 26;
  const static unsigned pow2 = 26*26;
  const static unsigned max  = pow1 + pow2 + 26 * pow2;

  if (i < pow1)
    {
      char c = 'A' + i % pow1;
      return std::string(&c,&c+1);
    }

  if (i > max)
    throw std::overflow_error
      ("Value too large for transformation into Excel column heading.");

  i -= pow1;
  char char1 = 'A' + (i / pow2) - 1;
  char char2 = 'A' + (i%pow2) / pow1;
  char char3 = 'A' + i % pow1;

  if (char1 < 'A')
    return std::string(&char2,&char2 + 1) + char3;
  else
    return std::string(&char1,&char1 + 1) + char2 + char3;
}
于 2013-06-27T05:07:02.883 に答える
0

生成しようとしている結果は、文字「A」から「Z」を 26 桁として使用して、基数 27 の数値として表示できます。「A」は実際には「0」ですが、2 桁の数字になると「AA」になります (通常の 2 桁はBA次のようになります)。番号9以降は10)。その奇妙さを補うために、かなり小さな調整を行う必要があります。

通常のint(または何でも)カウントを行い、必要に応じて27進数に変換できます。それ以上の列をサポートしているとは思わないので、このバージョンを 2 桁に制限しましたが、それ以上に拡張することはかなり簡単です。

std::string to_excel_column(int input) { 
    int digit1 = input % 26;
    int digit2 = input / 26;

    std::string result;
    if (input > 26)
        result.push_back(digit2 + 'A' - 1);
    result.push_back(digit1 + 'A');
    return result;
}
于 2013-06-27T05:34:03.697 に答える