4

ある Excel ワークシートからデータを選択して別のワークシートにコピーする必要がありますが、データをコピーするプロセス中に次のことを達成する必要があります。

  • 元のワークシートの行ごとに、列ごとにセルを選択します (これは、おそらく配列などを使用して事前に定義できます)。

  • データを操作して、新しいワークシートでの向きを変更します。以下のスクリーンショットを参照してください。

私が言いたいことを正確に説明するのは難しいので、私のスクリーンショットが私が必要としているものを伝えてくれることを願っています.

ここに画像の説明を入力

各行にはチャネル値があり、すべての結果をチャネルごとに並べ替えて要約する必要があります。制限に対して結果をチェックする必要もありますが、この問題が解決された後、それを超えることができます。

以下にコードを示します。これは私の最初のスクリプトであるため、エラーが発生する可能性があります。チャネルごとにデータを並べ替えてもかまいません。これまでのところ、必要な列を選択して新しいワークシートに正確にコピーするのに苦労しています。

コードの最初の部分は、新しいワークシートを確認して作成することです。その後、必要な列を事前定義できる変数と配列を定義します。x行数をチェックするループで終了し(ただし、行の数だけ繰り返したい)、その中に行ごとに別のループがあり、定義済みの列に基づいてセルを取得します。

デバッグ時に、ループ内の一番下にあるシート コピー関数のオブジェクトまたはアプリケーション エラーとして表示されます。どこが間違っているのかわかりません。これを攻撃するより良い方法はありますか?

Sub Process_Results()

'User defines the worksheets for this script
sourcedatasheet_name = InputBox("Enter the customer data sheet name: ", "Enter Worksheet Name")

For rep = 1 To (Worksheets.Count)
    If LCase(Sheets(rep).Name) = LCase(sourcedatasheet_name) Then
        Exit For
    ElseIf (rep = Worksheets.Count) And (LCase(Sheets(rep).Name) <> LCase(sourcedatasheet_name)) Then
        MsgBox "This sheet does not exist!"
        Exit Sub
    End If
Next

destinationdatasheet_name = InputBox("Enter the destination worksheet name to write the data to: ", "Enter Destination Worksheet Name")
For rep = 1 To (Worksheets.Count)
    If LCase(Sheets(rep).Name) = LCase(destinationdatasheet_name) Then
        MsgBox "This sheet already exists!"
        Exit Sub
    End If
Next

Sheets.Add After:=Sheets(Sheets.Count)
Sheets(ActiveSheet.Name).Name = destinationdatasheet_name

'These are the variables for referencing data sets in the source sheet
Dim source_testmodel
Dim source_testcasename
Dim source_measurementname
Dim source_carrierfrequency
Dim source_limitlow
Dim source_limithigh
Dim source_measuredresult
Dim source_measurementunit

'These are the variables for referencing data set columns in the processed data sheet
Dim destination_testmodel
Dim destination_testcasename
Dim destination_measurementname
Dim destination_carrierfrequency_bottomchannel
Dim destination_carrierfrequency_middlechannel
Dim destination_carrierfrequency_topchannel
Dim destination_measuredresult

'Define the column number and cell column reference for each data set that will be used to retrieve information from the source sheet
source_testmodel = 9
source_testname = 11
source_measurementname = 12
source_measuredcarrierfrequency = 13
source_measurementlimitlow = 15
source_measurementlimithigh = 16
source_measuredresult = 17
source_measurementunit = 18

Dim array_source_fields(8) As Variant
array_source_fields(1) = source_testmodel
array_source_fields(2) = source_testname
array_source_fields(3) = source_measurementname
array_source_fields(4) = source_measuredcarrierfrequency
array_source_fields(5) = source_measurementlimitlow
array_source_fields(6) = source_measurementlimithigh
array_source_fields(7) = source_measuredresult
array_source_fields(8) = source_measurementunit

'Define the column number and cell column reference for each data set that will be used to write information to the processing sheet
destination_testmodel = 1
destination_testname = 2
destination_measurementname = 3
destination_channelbottom = 4
destination_channelmiddle = 5
destination_channeltop = 6

Dim array_processed_fields(6) As Variant
array_processed_fields(1) = destination_testmodel
array_processed_fields(2) = destination_testname
array_processed_fields(3) = destination_measurementname
array_processed_fields(4) = destination_channelbottom
array_processed_fields(5) = destination_channelmiddle
array_processed_fields(6) = destination_channeltop

'Start processing data

Dim y As Variant
Dim lastrow As Long


For x = 1 To 100 'row 'lastrow=activesheet.usedrange.specialcells(xlCellTypeLastCell)
    For Each y In array_source_fields 'y = LBound(Application.Transpose(array_source_fields)) To UBound(Application.Transpose(array_source_fields))
        Sheets(sourcedatasheet_name).Cells(x, y).Copy Destination:=Sheets(destinationdatasheet_name).Cells(x, y)
    Next y


Next x




End Sub
4

2 に答える 2

1

これを解決する方法は複数あります!このファイルには次の 3 つが含まれています。 ここに画像の説明を入力

1.ピボットテーブル

  1. 挿入タブ->テーブル-> ピボットテーブル
  2. 分析する範囲としてデータを選択し、[OK] をクリックします。
  3. Modeフィールドを「行ラベル」ボックスに、「チャネル」を列「列ラベル」に、「結果」を「値」にドラッグします。
  4. ピボットテーブル ツール-> [デザイン] タブ-> [レイアウト] -> [総計] -> [行と列のオフ]

終わり!

2.公式

この解決策は、モードとチャンネルの名前がわかっている場合にのみ適用できます。

  1. すべてのモード名を最初の列に配置し、すべてのチャネル名を最初の行に配置します。つまり、ヘッダー行を作成します。以下の式では、ヘッダー行が行 1 で、ヘッダー列がシート 2 の A であり、データがセル A1 から始まるシート 1 にあると仮定します
  2. セル B2 に次の数式を入力します。
=INDEX(Sheet1!$D$2:$D$10,MATCH($A2&"_"&B$1,Sheet1!$A$2:$A$10&"_"&Sheet1!$C$2:$C$10,0))

これは配列数式です。つまり、次のように入力します。 Ctrl- Shift- Enter 3. 数式を表の残りのすべてのセルにコピーします。

3.マクロ

このマクロは、モードとチャネルがソートされていることを前提としていますが、仕事をします。結果テーブルの左上のセルに名前を付けて、次のrngHeaderコードを実行する必要があります。

Sub FillTable()
    Dim rngSource As Range, rngTarget As Range
    Dim lngModeCount As Long, lngChannelCount As Long

    Set rngSource = Range("A2")
    Set rngTarget = Range("rngHeader")

    'Clear old result
    With rngTarget
        If .Offset(1) <> "" And .Offset(, 1) <> "" Then
            .Resize(.End(xlDown).Row - .Row + 1, .End(xlToRight).Column - .Column + 1).Clear
            rngTarget = "(cell is named ""rngHeader"")"
        End If
    End With

    While rngSource.Value <> ""
        If rngSource.Offset(-1) <> rngSource Then
            lngModeCount = lngModeCount + 1
            lngChannelCount = 0
            rngTarget.Offset(lngModeCount) = rngSource
            rngTarget.Offset(lngModeCount).Font.Bold = True
        End If
        lngChannelCount = lngChannelCount + 1
        If lngModeCount = 1 Then
            rngTarget.Offset(, lngChannelCount) = rngSource.Offset(, 2)
            rngTarget.Offset(, lngChannelCount).Font.Bold = True
        End If
        rngTarget.Offset(lngModeCount, lngChannelCount) = rngSource.Offset(, 3)
        Set rngSource = rngSource.Offset(1)
    Wend

End Sub
于 2013-02-24T20:21:36.883 に答える
1

ところで、ここにあなたが望むことをするいくつかのコードがあります:

Const FIRST_CELL_IN_SOURCE_DATA = "$A$4"
Const FIRST_CELL_IN_DEST_DATA = "$A$2"

Const COL_SOURCE_MODE = 0
Const COL_SOURCE_DESC = 1
Const COL_SOURCE_CHANNEL = 2
Const COL_SOURCE_RESULT = 3
Const COL_SOURCE_LIMIT = 4

Const COL_DEST_MODE = 1
Const COL_DEST_DESC = 1
Const COL_DEST_RESULT = 4
Const COL_DEST_FIRST_CHANNEL = 3

Const ROW_DEST_HEADER = 1

Private wksSource As Worksheet
Private wksDest As Worksheet

Sub Process_Results()

If GetSourceSheet = False Then Exit Sub
If CreateDestinationSheet = False Then Exit Sub
CopyDataSet

End Sub

Private Function GetSourceSheet() As String

'User defines the worksheets for this script
sourcedatasheet_name = InputBox("Enter the customer data sheet name: ", "Enter Worksheet Name")

For rep = 1 To (Worksheets.Count)
    If LCase(Sheets(rep).Name) = LCase(sourcedatasheet_name) Then
        Exit For
    ElseIf (rep = Worksheets.Count) And (LCase(Sheets(rep).Name) <> LCase(sourcedatasheet_name)) Then
        MsgBox "This sheet does not exist!"
        Exit Function
    End If
Next

Set wksSource = Sheets(sourcedatasheet_name)
GetSourceSheet = True

End Function

Private Function CreateDestinationSheet() As String

destinationdatasheet_name = InputBox("Enter the destination worksheet name to write the data to: ", "Enter Destination Worksheet Name")
For rep = 1 To (Worksheets.Count)
    If LCase(Sheets(rep).Name) = LCase(destinationdatasheet_name) Then
        MsgBox "This sheet already exists!"
        Exit Function
    End If
Next

Sheets.Add After:=Sheets(Sheets.Count)
Sheets(ActiveSheet.Name).Name = destinationdatasheet_name

Set wksDest = Sheets(destinationdatasheet_name)
AddHeaders
CreateDestinationSheet = True

End Function

Private Sub CopyDataSet()

Dim rngSourceRange As Range
Dim rngDestRange As Range

Set rngSourceRange = wksSource.Range(FIRST_CELL_IN_SOURCE_DATA)
Set rngDestRange = wksDest.Range(FIRST_CELL_IN_DEST_DATA)
rngDestRange.Activate

Do Until rngSourceRange.Value = ""
    CopyRowToDest rngSourceRange, rngDestRange
    Set rngSourceRange = rngSourceRange.Offset(1)
Loop

End Sub

Private Sub AddHeaders()

Dim rng As Range
Set rng = wksDest.Cells(ROW_DEST_HEADER, 1)

rng.Value = "Mode"
rng.Offset(, 1).Value = "Test"

End Sub

Private Function GetColumnForChannel(ByVal Channel As String) As Long

Dim rng As Range
Set rng = wksDest.Cells(ROW_DEST_HEADER, COL_DEST_FIRST_CHANNEL)

Do Until rng.Value = ""
    If rng.Value = Channel Then
        GetColumnForChannel = rng.Column - 1
        Exit Function
    End If
    Set rng = rng.Offset(, 1)
Loop

rng.Value = Channel
GetColumnForChannel = rng.Column - 1

End Function

Private Sub MoveToModeRow(ByVal Mode As String)

If ActiveCell.Value = Mode Then Exit Sub

If ActiveCell.Address = FIRST_CELL_IN_DEST_DATA And ActiveCell.Value = "" Then
    ActiveCell.Value = Mode
    Exit Sub
End If

If Val(ActiveCell.Value) < Val(Mode) And ActiveCell.Offset(1).Value = "" Then
    ActiveCell.Offset(1).Activate
    ActiveCell.Value = Mode
    Exit Sub
End If

Dim rng As Range
Set rng = wksDest.Range(FIRST_CELL_IN_DEST_DATA)

Do Until rng.Value = ""
    If rng.Value = Mode Then
        rng.Activate
        Exit Sub
    End If
    Set rng = rng.Offset(1)
Loop

rng.Value = Mode
rng.Activate

End Sub



Private Sub CopyRowToDest(ByRef rngSourceRange As Range, ByRef rngDestRange As Range)

MoveToModeRow rngSourceRange.Offset(, COL_SOURCE_MODE).Value

Dim lngCol As Long
lngCol = GetColumnForChannel(rngSourceRange.Offset(, COL_SOURCE_CHANNEL).Value)

ActiveCell.Offset(, lngCol).Value = rngSourceRange.Offset(, COL_SOURCE_RESULT).Value
ActiveCell.Offset(, COL_DEST_DESC).Value = rngSourceRange.Offset(, COL_SOURCE_DESC).Value

End Sub
于 2013-02-24T18:02:30.820 に答える