2

次のようなデータ行があります。

            header1      header2      header3      header4      header5
row key     datavalue1   datavalue2   datavalue3   datavalue4   datavalue5....

基本的に、データ値が行ごとに空である場合と空でない場合がある非正規化されたデータセットがあります。それらを正規化する必要があります。

すなわち

12345678    NULL         10           3            NULL         14

次のようになります。

12345678   header2   10
12345678   header3   3
12345678   header5   14

特殊な貼り付け変換を使用してこれを行うこともできますが、何千もの行があり、それぞれに適切な行キーを取得する必要があります。さらに、各行には一連の記述が関連付けられており、各データ値でコピーする必要があります。

空でないすべてのデータ値と関連するデータ値の参照を含む単一の列の複数の行を持つように、列の各行を変換する最も簡単な方法は何ですか? データセットをピボットできる必要があります。

4

5 に答える 5

3

「ヘッダー」列が 5 つある場合は、次の数式を入力します

H1: =OFFSET($A$1,INT((ROW()-1)/5)+1,0)
I1: =OFFSET($A$1,0,IF(MOD(ROW(),5)=0,5,MOD(ROW(),5)))
J1: =INDEX($A$1:$F$9,MATCH(H1,$A$1:$A$9,FALSE),MATCH(I1,$A$1:$F$1,FALSE))

H1:J?? をコピー 特別な値を上に貼り付けます。列 J で並べ替え、ゼロをすべて削除します。データに正当なゼロがある場合は、最初に空白のセルを一意の文字列に置き換えてから、後で削除する必要があります。

それ以上の列がある場合は、上記のすべての数式の「5」を任意の数値に置き換えます。

于 2009-11-23T19:58:51.077 に答える
1

あなたがやろうとしていることの一部は、ピボットテーブルを「デピボット」することだと私には思えます。同様のタスクを実行する必要がある場合、このヒントは非常に役立ちます。http: //spreadsheetpage.com/index.php/tip/creating_a_database_table_from_a_summary_table/

Excel 2007では、キーストロークAlt + D、Pを使用して、古いExcel2003ピボットテーブルウィザードにアクセスできることに注意してください。

于 2010-06-10T13:07:07.853 に答える
1

Excel には、ニーズに対応できる転置機能があります。かなり隠れていて少し不器用ですが、VBA を掘り下げるよりは簡単でしょう。以下は、Excel 2007 ヘルプからの抜粋です。

Blockquote 列と行の切り替え (転置) すべて表示 すべて非表示 データが列または行に入力されているが、そのデータを行または列に再配置する場合は、データを一方から他方にすばやく転置できます。

たとえば、次の図に示すように、列に編成された地域の売上データは、データを転置した後に行に表示されます。

1. ワークシートで、次の操作を行います。 データを列から行に再配置するには、データを含む列のセルを選択します。行から列にデータを再配置するには、データを含む行のセルを選択します。2. [ホーム] タブの [クリップボード] グループで、[コピー] をクリックします。

キーボード ショートカット 選択したデータをコピーするには、CTRL+C を押すこともできます。

注 データを再配置するには、[コピー] コマンドのみを使用できます。この手順を正常に完了するには、Cut コマンドを使用しないでください。

3.ワークシートで、コピーしたデータを再配置する行または列の最初のセルを選択します。注 コピー領域 (コピー領域: データを別の場所に貼り付けるときにコピーするセル。セルをコピーすると、セルの周りに移動境界線が表示され、コピーされたことを示します。) と貼り付け領域 (貼り付け領域: Office クリップボードを使用して切り取りまたはコピーされたデータの対象先は重複できません。データのコピー元の領域の外側にある貼り付け領域のセルを選択していることを確認してください。

4. [ホーム] タブの [クリップボード] グループで、[貼り付け] の下の矢印をクリックし、[転置] をクリックします。5.データの転置が正常に完了したら、コピー領域のデータを削除できます。ヒント 転置するセルに数式が含まれている場合、数式が転置され、転置されたセル内のデータへのセル参照が自動的に調整されます。数式が転置されていないセルのデータを引き続き正しく参照できるようにするには、転置する前に数式で絶対参照を使用します。

詳細については、「相対参照、絶対参照、および混合参照を切り替える」を参照してください。

引用符

于 2011-10-24T21:53:17.673 に答える
0

各行をループしてデータを別のページに出力するVBAマクロを作成します。これにより、データが出力されたら、新しいページにピボットテーブルを作成できます。

VBAにどれだけ慣れているかはわかりませんが、データを配列(または、本当に正しく実行したい場合はオブジェクトのコレクション)にロードして書き戻すことで、これを簡単に行うことができます。

これは、優れたVBAドキュメントへのリンクです。

http://social.msdn.microsoft.com/Forums/en/isvvba/thread/d712dbdd-c876-4fe2-86d2-7d6323b4262c

編集

これは完全に機能するソリューションではなく、正しい方向に役立つ一般的なフレームワークであることに注意してください。

あなたがしなければならないことの多くを行う一般的な例として(最善の方法ではありませんが、おそらく初心者にとっては最も簡単です)、ワークシートをもっと見ずに言うのは難しいですが、このようなものがあなたを始めるはずです。

Sub RowsToColumns ()
  Application.ScreenUpdating = False
  Dim srcWrkSheet As Worksheet
  Dim destWrkSheet As Worksheet
  Dim excelData as pExcelData
  Dim srcRowNumber As Long
  Dim srcRolNumber As Long
  Dim destRowNumber As Long
  Dim destColNumber As Long

  SET srcWrkSheet = Sheets("YourSourceWorkSheetName")
  SET destWrkSheet = Sheets("YourDestinationWorkSheetName")

  srcRowNumber = 1
  srcColNumber = 1
  destRowNumber = 1
  destColNumber = 1

  'Loop until blank row is encountered in column 1
  Do
    destWrkSheet.Cells(destRowNumber ,1).Value = "Header 1 " & srcWrkSheet.Cells(srcRowNumber,srcColNumber )
    destWrkSheet.Cells(destRowNumber ,1).Value = "Header 2 " & srcWrkSheet.Cells(srcRowNumber ,srcColNumber)

    srcRowNumber = srcRowNumber + 1
    srcColNumber = srcColNumber + 1
    destRowNumber = destRowNumber  + 1
  Loop Until srcWrkSheet .Cells(rowNumber, 1).value = ""

End Sub
于 2009-11-23T17:12:48.977 に答える
0

VBA で考えられる解決策を見てみましょう。これは本当に役立つと思います。私のコードについて知っておくべきことがいくつかあります。

  • このコードを VBA のコード モジュールに配置する必要があります (マクロと同じ場所)。
  • 私がシートに名前を付けたものを見てください:オリジナルと正規化。シート名またはコードを変更する必要があります
  • の文字列フィールドで値をチェックしていますNULL。セルが空の場合は、If IsEmpty(rngCurrent.Value) Then代わりにチェックする必要があります。

'

Sub NormalizeSheet()
Dim wsOriginal As Worksheet
Dim wsNormalized As Worksheet
Dim strKey As String
Dim clnHeader As Collection
Dim lngColumnCounter As Long
Dim lngRowCounterOriginal As Long
Dim lngRowCounterNormalized As Long
Dim rngCurrent As Range
Dim varColumn As Variant

Set wsOriginal = ThisWorkbook.Worksheets("Original")     'This is the name of your original worksheet'
Set wsNormalized = ThisWorkbook.Worksheets("Normalized") 'This is the name of the new worksheet'
Set clnHeader = New Collection

wsNormalized.Cells.ClearContents        'This deletes the contents of the destination worksheet'

lngColumnCounter = 2
lngRowCounterOriginal = 1
Set rngCurrent = wsOriginal.Cells(lngRowCounterOriginal, lngColumnCounter)

' We'll loop through just the headers to get a collection of header names'
Do Until IsEmpty(rngCurrent.Value)
    clnHeader.Add rngCurrent.Value, CStr(lngColumnCounter)
    lngColumnCounter = lngColumnCounter + 1
    Set rngCurrent = wsOriginal.Cells(lngRowCounterOriginal, lngColumnCounter)
Loop

'Here we'll reset our Row Counter and loop through the entire data set'
lngRowCounterOriginal = 2
lngRowCounterNormalized = 1
lngColumnCounter = 1

Do While Not IsEmpty(wsOriginal.Cells(lngRowCounterOriginal, lngColumnCounter))

    Set rngCurrent = wsOriginal.Cells(lngRowCounterOriginal, lngColumnCounter)
    strKey = rngCurrent.Value ' Get the key value from the current cell'
    lngColumnCounter = 2

    'This next loop parses the denormalized values for each row'
    Do While Not IsEmpty(wsOriginal.Cells(lngRowCounterOriginal, lngColumnCounter))
        Set rngCurrent = wsOriginal.Cells(lngRowCounterOriginal, lngColumnCounter)

        'We're going to check to see if the current value'
        'is equal to NULL. If it is, we won't add it to'
        'the Normalized Table.'
        If rngCurrent.Value = "NULL" Then
            'Skip it'
        Else
            'Add this item to the normalized sheet'
            wsNormalized.Range("A" & lngRowCounterNormalized).Value = strKey
            wsNormalized.Range("B" & lngRowCounterNormalized).Value = clnHeader(CStr(lngColumnCounter))
            wsNormalized.Range("C" & lngRowCounterNormalized).Value = rngCurrent.Value
            lngRowCounterNormalized = lngRowCounterNormalized + 1
        End If

        lngColumnCounter = lngColumnCounter + 1
    Loop
    lngRowCounterOriginal = lngRowCounterOriginal + 1
    lngColumnCounter = 1    'We reset the column counter here because we're on a new row'
Loop



End Sub
于 2009-11-23T20:06:26.053 に答える