Excel (VBA)

Excel VBAに関するフォーラムです。
  • 解決済みのトピックにはコメントできません。
このトピックは解決済みです。
質問

 
(指定なし : 指定なし)
転記について
投稿日時: 23/10/12 06:37:38
投稿者: yama1006
メールを送信

いつもお世話になっております。
 
下記のようにコードを組みました。
ary1に転記範囲を指定してF列の数値を24で割った数をK6から転記するようなコードです。
 
なのですが、同じ数値が計算されてしまい、どこが間違っているか分かりません。
 
また他に良い方法があれば教えていただけますでしょうか。
 
maxrow2 = ws1.Cells(Rows.Count, 1).End(xlUp).Row 'ws1の最終行
 
ary1 = ws1.Range(ws1.Cells(6, 11), ws1.Cells(maxrow2, 13)) ’転記範囲
 
For i = 6 To UBound(ary1) ’転記
 
    For l = 1 To UBound(ary1)
 
    ary1(l, 1) = ws1.Cells(i, 6) / 24
 
Next
 
    Next
 
ws1.Range("k6").Resize(UBound(ary1), UBound(ary1, 2)) = ary1 ’K6の11列から13行まで転記

回答
投稿日時: 23/10/12 07:44:34
投稿者: WinArrow

>同じ数値が計算されてしまい、どこが間違っているか分かりません。
 
ステップ実行で、変数の値を確認してみましょう。

回答
投稿日時: 23/10/12 07:50:41
投稿者: WinArrow

>ary1に転記範囲を指定して
この当たりを誤解しているでしょうね?
 
転記範囲とは、何を指しているだろうか?

回答
投稿日時: 23/10/12 08:23:51
投稿者: WinArrow

ループを使わずに、
一般操作で、できますよ。
 
作業セルとして、セルJ1を使います。J1に24を入力しておきます。
手順
(1)F11〜F13をK6〜K8で複写します。
(2)J1をコピー
(3)K6〜K8を選択して、「形式を指定して貼り付け」→「値」、「除算」をON →OK]
(4)[Esc]
で完了です。

回答
投稿日時: 23/10/12 08:56:33
投稿者: WinArrow

前レスの操作をマクロの記録で作成したコードをアレンジしたコードを紹介します。

Dim MaxRow As Long
Dim ws1 As Worksheet
Dim MOTOCELL As Range, SAKICELL As Range

    Set ws1 = ActiveSheet
    With ws1
        .Range("J1").Value = 24
        MaxRow = .Range("F" & .Rows.Count).End(xlUp).Row
        Set MOTOCELL = .Range(.Range("F11"), Cells(MaxRow, "F"))
        MOTOCELL.Copy Destination:=.Range("K6")
        Set SAKICELL = Selection
        .Range("J1").Copy
        SAKICELL.PasteSpecial _
            Paste:=xlPasteAll, _
            Operation:=xlDivide
        Set MOTOCELL = Nothing
        Set SAKICELL = Nothing
    End With
    Application.CutCopyMode = False

回答
投稿日時: 23/10/12 15:37:33
投稿者: WinArrow

前レスは、少し勘違いしているところがありますので、
下記の確認がクリアになた時点で書き直します。
  
確認&質問
 

引用:

maxrow2 = ws1.Cells(Rows.Count, 1).End(xlUp).Row 'ws1の最終行

↑転記する元セル範囲は、F列セルですよね?
A列の最終行とF列の最終行は同じと考えてよいですか?
引用:
ary1 = ws1.Range(ws1.Cells(6, 11), ws1.Cells(maxrow2, 13)) ’転記範囲

maxrow2が仮に10として
↑のコードは、ary1 にK6〜M10の値が入ります。
ループ処理の中では、1列目(つまり、K列)しか対象にならないのに
何故、M列まで配列変数にいれているのですか?
  
引用:

For i = 6 To UBound(ary1) ’転記
    For l = 1 To UBound(ary1)
    ary1(l, 1) = ws1.Cells(i, 6) / 24
  Next
 Next

F列のループには、「i」を使ううていますが、
その都度、ary1の1列目に代入していますから、
最終的に、F列最終行の値/24の結果が入ります。
ary1の1列目は、K列セルに代入されますが、
間違いありませんか?
 
この処理の結果は、F6〜Fxxの値/24の値がK6〜Kxxに入れていることになりませんか?
  
  

回答
投稿日時: 23/10/12 17:40:27
投稿者: WinArrow

コーディング時のアドバイス
変数名として使用する文字について
変数名には、意味が分かるような名前を付けましょう。
「i」(アイ)「l」(エル)は、「1」と間違えやすいので、使用しない方が無難です。
 
セルに使う場合は、
Cells(RowX, 6)でhなく、Cells(Rowx, "F")のように記述できます。
可読性を重視することをお勧めします。

投稿日時: 23/10/12 22:20:43
投稿者: yama1006
メールを送信

 
 

引用:

maxrow2 = ws1.Cells(Rows.Count, 1).End(xlUp).Row 'ws1の最終行

↑転記する元セル範囲は、F列セルですよね?
A列の最終行とF列の最終行は同じと考えてよいですか?
引用:
ary1 = ws1.Range(ws1.Cells(6, 11), ws1.Cells(maxrow2, 13)) ’転記範囲

 
こちらご認識のとおりです。
 
maxrow2が仮に10として
↑のコードは、ary1 にK6〜M10の値が入ります。
ループ処理の中では、1列目(つまり、K列)しか対象にならないのに
何故、M列まで配列変数にいれているのですか?
 
M列まで別のコードを入れることを想定しているからです。
まずはK6〜最終行までの処理を行いたいと思っております。
  
引用:

For i = 6 To UBound(ary1) ’転記
    For l = 1 To UBound(ary1)
    ary1(l, 1) = ws1.Cells(i, 6) / 24
  Next
 Next

F列のループには、「i」を使ううていますが、
その都度、ary1の1列目に代入していますから、
最終的に、F列最終行の値/24の結果が入ります。
ary1の1列目は、K列セルに代入されますが、
間違いありませんか?
 
この処理の結果は、F6〜Fxxの値/24の値がK6〜Kxxに入れていることになりませんか?
  
  
[/quote]
 
f6〜f列最終行を24で割った数値がK6〜最終行まで入るような処理をしたいです。
 
お手数をおかけします。よろしくお願いいたします。

回答
投稿日時: 23/10/12 22:32:46
投稿者: WinArrow

再掲(但し、元転記セル範囲は修正してあります。
ループを使わずに、
一般操作で、できますよ。
  
作業セルとして、セルJ1を使います。J1に24を入力しておきます。
手順
(1)F6〜FxxをK6〜Kxxで複写します。
(2)J1をコピー
(3)K6〜Kxxを選択して、「形式を指定して貼り付け」→「値」、「除算」をON →OK]
(4)[Esc]
で完了です。
 
 
これをVBAコードにしてあります。
J1セルは、都合のよいセルに変更してください。

Dim MaxRow As Long
Dim ws1 As Worksheet
Dim MOTOCELL As Range, SAKICELL As Range

    Set ws1 = ActiveSheet
    With ws1
        .Range("J1").Value = 24
        MaxRow = .Range("F" & .Rows.Count).End(xlUp).Row
        Set MOTOCELL = .Range(.Range("F6"), Cells(MaxRow, "F"))
        MOTOCELL.Copy Destination:=.Range("K6")
        Set SAKICELL = Selection
        .Range("J1").Copy
        SAKICELL.PasteSpecial _
            Paste:=xlPasteAll, _
            Operation:=xlDivide
        Set MOTOCELL = Nothing
        Set SAKICELL = Nothing
    End With
    Application.CutCopyMode = False

回答
投稿日時: 23/10/13 02:15:10
投稿者: hatena
投稿者のウェブサイトに移動

引用:
ary1に転記範囲を指定してF列の数値を24で割った数をK6から転記するようなコードです。

1列の数値を24でわって転記するなら2重ループにする必要はないです。
 
2重ループにしているために配列の1列目を繰り返し上書きしているため同じ値になってしまいます。
ステップ実行してみてどのセルを代入しているかを確認すれば理解できるでしょう。
 
提示のコードを修正するなら例えば下記のような感じです。
 
    Dim i As Long, maxrow2 As Long
    Dim ary1()
    Dim ws1 As Worksheet
    Set ws1 = ActiveSheet
    
    maxrow2 = ws1.Cells(Rows.Count, "F").End(xlUp).Row 'ws1のF列の最終行
 
    ary1 = ws1.Range(ws1.Cells(6, "K"), ws1.Cells(maxrow2, "L")) '転記先範囲を配列に
 
    For i = LBound(ary1) To UBound(ary1)
             '配列の先頭行は1, 転記元範囲の先頭行は6なので、行位置の差は5
            ary1(i, 1) = ws1.Cells(i + 5, "F") / 24
    Next
  
    ws1.Range("k6").Resize(UBound(ary1), UBound(ary1, 2)) = ary1 

 
配列を使うなら、転記元も配列にした方がわかりやすいかな。
 
 
 
Evaluateメソッドを使えばループを使わなくてもできます。
 
    Dim ws1 As Worksheet
    Set ws1 = ActiveSheet
    
    Dim MaxRow As Long
    MaxRow = ws1.Range("F" & ws1.Rows.Count).End(xlUp).Row
 
    ws1.Range("K6:K" & MaxRow).Value = ws1.Evaluate("F6:F" & MaxRow & "/24")

投稿日時: 23/10/13 07:01:36
投稿者: yama1006
メールを送信

WinArrow さんの引用:
コーディング時のアドバイス
変数名として使用する文字について
変数名には、意味が分かるような名前を付けましょう。
「i」(アイ)「l」(エル)は、「1」と間違えやすいので、使用しない方が無難です。
 
セルに使う場合は、
Cells(RowX, 6)でhなく、Cells(Rowx, "F")のように記述できます。
可読性を重視することをお勧めします。

 
こちら、アドバイスありがとうございます。

投稿日時: 23/10/13 07:02:41
投稿者: yama1006
メールを送信

WinArrow さんの引用:
再掲(但し、元転記セル範囲は修正してあります。
ループを使わずに、
一般操作で、できますよ。
  
作業セルとして、セルJ1を使います。J1に24を入力しておきます。
手順
(1)F6〜FxxをK6〜Kxxで複写します。
(2)J1をコピー
(3)K6〜Kxxを選択して、「形式を指定して貼り付け」→「値」、「除算」をON →OK]
(4)[Esc]
で完了です。
 
 
これをVBAコードにしてあります。
J1セルは、都合のよいセルに変更してください。
Dim MaxRow As Long
Dim ws1 As Worksheet
Dim MOTOCELL As Range, SAKICELL As Range

    Set ws1 = ActiveSheet
    With ws1
        .Range("J1").Value = 24
        MaxRow = .Range("F" & .Rows.Count).End(xlUp).Row
        Set MOTOCELL = .Range(.Range("F6"), Cells(MaxRow, "F"))
        MOTOCELL.Copy Destination:=.Range("K6")
        Set SAKICELL = Selection
        .Range("J1").Copy
        SAKICELL.PasteSpecial _
            Paste:=xlPasteAll, _
            Operation:=xlDivide
        Set MOTOCELL = Nothing
        Set SAKICELL = Nothing
    End With
    Application.CutCopyMode = False

 
ありがとうございます。参考にします

投稿日時: 23/10/13 07:07:03
投稿者: yama1006
メールを送信

hatena さんの引用:
引用:
ary1に転記範囲を指定してF列の数値を24で割った数をK6から転記するようなコードです。

1列の数値を24でわって転記するなら2重ループにする必要はないです。
 
2重ループにしているために配列の1列目を繰り返し上書きしているため同じ値になってしまいます。
ステップ実行してみてどのセルを代入しているかを確認すれば理解できるでしょう。
 
提示のコードを修正するなら例えば下記のような感じです。
 
    Dim i As Long, maxrow2 As Long
    Dim ary1()
    Dim ws1 As Worksheet
    Set ws1 = ActiveSheet
    
    maxrow2 = ws1.Cells(Rows.Count, "F").End(xlUp).Row 'ws1のF列の最終行
 
    ary1 = ws1.Range(ws1.Cells(6, "K"), ws1.Cells(maxrow2, "L")) '転記先範囲を配列に
 
    For i = LBound(ary1) To UBound(ary1)
             '配列の先頭行は1, 転記元範囲の先頭行は6なので、行位置の差は5
            ary1(i, 1) = ws1.Cells(i + 5, "F") / 24
    Next
  
    ws1.Range("k6").Resize(UBound(ary1), UBound(ary1, 2)) = ary1 

 
配列を使うなら、転記元も配列にした方がわかりやすいかな。
 
 
 
Evaluateメソッドを使えばループを使わなくてもできます。
 
    Dim ws1 As Worksheet
    Set ws1 = ActiveSheet
    
    Dim MaxRow As Long
    MaxRow = ws1.Range("F" & ws1.Rows.Count).End(xlUp).Row
 
    ws1.Range("K6:K" & MaxRow).Value = ws1.Evaluate("F6:F" & MaxRow & "/24")

 
大変参考になりました。配列の使い方、参考にさせていただきます。
 

投稿日時: 23/10/13 07:07:22
投稿者: yama1006
メールを送信

yama1006 さんの引用:
hatena さんの引用:
引用:
ary1に転記範囲を指定してF列の数値を24で割った数をK6から転記するようなコードです。

1列の数値を24でわって転記するなら2重ループにする必要はないです。
 
2重ループにしているために配列の1列目を繰り返し上書きしているため同じ値になってしまいます。
ステップ実行してみてどのセルを代入しているかを確認すれば理解できるでしょう。
 
提示のコードを修正するなら例えば下記のような感じです。
 
    Dim i As Long, maxrow2 As Long
    Dim ary1()
    Dim ws1 As Worksheet
    Set ws1 = ActiveSheet
    
    maxrow2 = ws1.Cells(Rows.Count, "F").End(xlUp).Row 'ws1のF列の最終行
 
    ary1 = ws1.Range(ws1.Cells(6, "K"), ws1.Cells(maxrow2, "L")) '転記先範囲を配列に
 
    For i = LBound(ary1) To UBound(ary1)
             '配列の先頭行は1, 転記元範囲の先頭行は6なので、行位置の差は5
            ary1(i, 1) = ws1.Cells(i + 5, "F") / 24
    Next
  
    ws1.Range("k6").Resize(UBound(ary1), UBound(ary1, 2)) = ary1 

 
配列を使うなら、転記元も配列にした方がわかりやすいかな。
 
 
 
Evaluateメソッドを使えばループを使わなくてもできます。
 
    Dim ws1 As Worksheet
    Set ws1 = ActiveSheet
    
    Dim MaxRow As Long
    MaxRow = ws1.Range("F" & ws1.Rows.Count).End(xlUp).Row
 
    ws1.Range("K6:K" & MaxRow).Value = ws1.Evaluate("F6:F" & MaxRow & "/24")

 
大変参考になりました。配列の使い方、参考にさせていただきます。