Excel VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


5561 / 13645 ツリー ←次へ | 前へ→

【50060】データ整理 07/7/6(金) 16:28 質問[未読]
【50061】Re:データ整理 Lindy 07/7/6(金) 16:51 発言[未読]
【50068】Re:データ整理 ichinose 07/7/7(土) 8:40 発言[未読]
【50095】Re:データ整理 07/7/8(日) 22:06 発言[未読]
【50099】Re:データ整理 07/7/9(月) 12:20 質問[未読]
【50117】Re:データ整理 ichinose 07/7/10(火) 7:47 発言[未読]
【50121】Re:データ整理 07/7/10(火) 10:54 発言[未読]
【50133】Re:データ整理 ichinose 07/7/10(火) 20:38 発言[未読]
【50138】Re:データ整理 Lindy 07/7/11(水) 10:15 発言[未読]
【50143】Re:データ整理 07/7/11(水) 12:02 お礼[未読]

【50060】データ整理
質問    - 07/7/6(金) 16:28 -

引用なし
パスワード
   今、金属を引っ張って圧縮というのを1サイクルとして、それを繰り返すという実験をしています。
データ数がおおいため、VBAで処理しようと思います。
各サイクルにおける引っ張る力の最大値、最小値を抜き出すプログラムはあるのですが、その最大、最小の時の他のデータも一緒に抜き出すにはどうしたらよいでしょうか?
かなりわかりづらいかと思いますが、イメージとしてはA列に入れたデータを上記のように抜き出し、その抜き出した値と同じ行のB列の値も抜き出したいということです。
ますますわかりづらいですがよろしくい願いします。

【50061】Re:データ整理
発言  Lindy  - 07/7/6(金) 16:51 -

引用なし
パスワード
   ▼林 さん:
こんにちは

この質問のされ方だと
回答者には貴方のシート構成もデータの中身も現在のコードも
見えないので回答してあげられません。と言われてしまうかもですよ(>_<)

考え方としては、A列に対してB列を抜くなら

 [抜き出し先] = [取得するA列のRangeオブジェクト].Value
 
となっているところの下に

 [抜き出し先] = [取得するA列のRangeオブジェクト].Offset(0,1).Value

という感じだと思います。

【50068】Re:データ整理
発言  ichinose  - 07/7/7(土) 8:40 -

引用なし
パスワード
   おはようございます。

>今、金属を引っ張って圧縮というのを1サイクルとして、それを繰り返すという実験をしています。
>データ数がおおいため、VBAで処理しようと思います。
>各サイクルにおける引っ張る力の最大値、最小値を抜き出すプログラムはあるのですが、その最大、最小の時の他のデータも一緒に抜き出すにはどうしたらよいでしょうか?

サンプルコードです。

新規ブックの標準モジュールに

以下のコードをコピーして下さい。

'===================================================================
Option Explicit
Sub main()
  Dim rng As Range
  Dim ans As Variant
  Dim rw As Variant
  Call sample 'サンプルデータの作成
  With ActiveSheet
    Set rng = .Range("a2", .Cells(.Rows.Count, "a").End(xlUp))
    If rng.Row > 1 Then
     With rng
       Debug.Print "transpose(if(" & _
             .Address & "=max(" & .Address & _
             "),row(" & .Address & "),""×""))"
       '↑こんな配列数式を評価しています
       'イミディエイトウインドーで確認してください
       ans = Filter(Evaluate("transpose(if(" & _
             .Address & "=max(" & .Address & _
             "),row(" & .Address & "),""×""))"), _
             "×", False)
       '最小値の場合は、↑の数式のmax---->minに変更
       End With
     For Each rw In ans
      MsgBox .Range("a" & rw).Value & "----" & .Range("b" & rw).Value
      Next
     End If
    End With
End Sub
'===================================================================
Sub sample()
  With ActiveSheet
    .Range("a1:b1").Value = Array("検索値", "参照データ")
    With .Range("a2:a31")
     .Formula = "=round(rand()*400,2)"
     .Value = .Value
     End With
    With .Range("b2:b31")
     .Formula = "=int(rand()*10000)+1"
     .Value = .Value
     End With
    End With
End Sub


上記のmainを実行するとアクティブシートに対して、
サンプルデータを作成し、そのサンプルデータに対して
A列の最大値とその最大値に対応するB列の値を表示します。

サンプルデータ(sampleというプロシジャーの実行で作成)は、
以下のようなデータです。


     A    B
 1  検索値  参照データ
 2  273.33   7569
 3  51.23    851
 4  367.71   2407
 5  160.6    2270
 6  143.8    5101
 7  353.74    161
 8  166.23    237
 9  228.17   2586
10  166.86   5910
 ・
 ・
 ・
A31まで作成します。
上記の例だと、A列最大値は、4行目の367.71ですから、

367.71 ----- 2407

と表示されます。

これが参考になりますか?


>かなりわかりづらいかと思いますが、イメージとしてはA列に入れたデータを上記のように抜き出し、その抜き出した値と同じ行のB列の値も抜き出したいということです。
>ますますわかりづらいですがよろしくい願いします。

こういう情報処理の問題では、

入力データの定義(例を必ず掲載)

出力データの定義(例を必ず掲載)

は不可欠ですよ!!

【50095】Re:データ整理
発言    - 07/7/8(日) 22:06 -

引用なし
パスワード
   Lindy さん ichinoseさん:

返信ありがとうございます。
いろいろ重なってしまって返信遅れてすみません・・

今あるデータ載せればよかったんですね(^ ^;
ちょっと今データが手元になく明日お二人のを参考にやってみます。
それからまた報告しますね。

すみませんです。

【50099】Re:データ整理
質問    - 07/7/9(月) 12:20 -

引用なし
パスワード
   おはようございます。
ちょっと試してみたのですがなかなかうまくいかず・・・

今あるデータは、

Public Sub Search_Stress()

Dim Stress(80000), Max_Stress(5000), Min_Stress(5000) As Double
Dim Cycle(5000) As Integer
Dim Num_MaxData(5000), Num_MinData(5000), i As Long
Dim Row0, Val_Check, ii, j As Integer
Dim Num_LoopData, End_Cycle As Integer
Dim Dir_Load As Integer
Dim Dum As Variant

Row0 = 1
Num_LoopData = 200
i = 1
j = 1

Max_Stress(0) = 0

'----引張りで開始の意味----
Dir_Load = 1


Search:
  
  Dum = Worksheets("Stress_Data").Cells(i + Row0, 1).Value
  
  If Dum = "" Then GoTo Wr_Data
  
  Stress(i) = Worksheets("Stress_Data").Cells(i + Row0, 1).Value
  
  If Dir_Load = 1 Then GoTo Tension Else GoTo Compression

Tension:
  If Stress(i) > Max_Stress(j) Then Max_Stress(j) = Stress(i) Else GoTo Check1
  
  Num_MaxData(j) = i
  
  GoTo Add_i
  
Check1:
  Val_Check = Val_Check + 1
  
  If Val_Check = 4 Then Cycle(j) = j: Val_Check = 0: Dir_Load = -1: Min_Stress(j) = Stress(i)
  
  GoTo Add_i
  

Compression:
  If Stress(i) < Min_Stress(j) Then Min_Stress(j) = Stress(i) Else GoTo Check2
  
  Num_MinData(j) = i
  
  GoTo Add_i
  
Check2:
  Val_Check = Val_Check + 1
  
  If Val_Check = 4 Then Val_Check = 0: j = j + 1: Dir_Load = 1: Max_Stress(j) = Stress(i)
  
  GoTo Add_i


Add_i:
  i = i + 1
  
 GoTo Search


Wr_Data:
  '----最大応力の妥当性のチェック-----
'  If Num_MaxData(j) - Num_MaxData(j - 1) < Num_LoopData * 0.5 Then End_Cycle = j - 1
   
    End_Cycle = j - 1
   
    Worksheets("Cycle_vs_MaxSg").Cells(Row0, 1).Value = "Cycle"
    Worksheets("Cycle_vs_MaxSg").Cells(Row0, 2).Value = "Max_Stress"
    Worksheets("Cycle_vs_MaxSg").Cells(Row0, 3).Value = "Min_Stress"
   
    For ii = 1 To End_Cycle
   
     Worksheets("Cycle_vs_MaxSg").Cells(ii + Row0, 1).Value = Cycle(ii)
     Worksheets("Cycle_vs_MaxSg").Cells(ii + Row0, 2).Value = Max_Stress(ii)
     Worksheets("Cycle_vs_MaxSg").Cells(ii + Row0, 3).Value = Min_Stress(ii)
    Next ii

End Sub


でA列にStressの値を入れて他のシートにCycle,Max_Stress,Min_Stressを書き出すというものです。それにプラスして抜き出したMax_Stress,Min_Stressの値と同じ行のB列の値も抜き出したいということです。

よろしければアドバイスお願いします。

【50117】Re:データ整理
発言  ichinose  - 07/7/10(火) 7:47 -

引用なし
パスワード
   ▼林 さん:
おはようございます。

まず、林さんが掲載されたコード・・・、
私がこの質問箱に参加して6,7年経ちますが、こういうコードを拝見するのは
2,3度です。つまり、それほど構造化プログラミング可能なVBAでは、
稀な記述です。

N88Basicか昔のFortran辺りからVBAに来られたのですか?
たとしたら、構造化プログラミングを行うことを検討してください。

ここで「構造化プログラミングとは?」を記述するのは、大変ですが、
手始めにGOTO文を使わずに掲載されたコードを書き直すことです。
GOTOは使用しなくても同じアルゴリズムを作成することは出来ます。

GOTO文を使わない = 構造化プログラミング

ではありませんが、まず、GOTO文を使わないでコーディングすることから
やり直すことを検討してください。

今のコードでは、失礼ながら、解析しようという意欲が私にはありません。

また、ご自分でも半年も経てば、
この内容を理解するのに相当苦労するのではないですか?

例えば、半年後に仕様変更が発生した場合とか・・・。


>
>でA列にStressの値を入れて他のシートにCycle,Max_Stress,Min_Stressを書き出すというものです。それにプラスして抜き出したMax_Stress,Min_Stressの値と同じ行のB列の値も抜き出したいということです。

それから、前回の投稿で

>こういう情報処理の問題では、

>入力データの定義(例を必ず掲載)

>出力データの定義(例を必ず掲載)

>は不可欠ですよ!!

と申し上げましたが、これの説明がありません。

林さんコードを

シートのStress_DataのA列に

   A
 1  データ
 2  166.39
 3  196.79
 4  329.79
 5  176.34
 6  361.07
 7  108.17
 8  50.77
 9  255.72
10  275.02
11  290.88
12  9.67
13  211.91
14  31.41
15  117.06
16  145.83
17  242.3
18  157.78
19  44.57
20  211.02
21  66.27
22  170.65
23  18.61
24  93.57
25  206.91
26  128.57
27  393.29
28  138.46
29  333.24
30  79.75
31  116.2


というデータで実行すると、

シートCycle_vs_MaxSgに

     A      B      C
 1  Cycle   Max_Stress  Min_Stress
 2   1     361.07     9.67
 3   2     242.3     18.61


という結果が得られます。

この例を引用して
このStress_Dataのデータと

Cycle_vs_MaxSgの結果の因果関係を説明してほしかったのです。

結果の最大値と最小値が何故、 2行なのか? 等。


こういう記述が不可欠だと申し上げたのです。

検討してみてください。

【50121】Re:データ整理
発言    - 07/7/10(火) 10:54 -

引用なし
パスワード
   ▼ichinose さん:

おはようございます。
何を説明するか勘違いしていました。すみません。

私はプログラミングとはまったく違う分野のものでしてこのコードも私が作ったものではなく前に作られたものなんです。

自分で勉強すればいいって話なんですがデータ出すまでにあまり時間もなく・・


それで定義なんですが、

金属をとある装置で引っ張って縮める、引っ張って縮める・・・と繰り返す実験を行います。その引っ張って縮めるまでを1サイクルとすると1,2,3,4,5,4,2,1というデータが得られるとします。縮め終えたらまた引っ張って縮める。これで2サイクルです。データとしては1サイクル目とあわせて1,2,3,4,5,4,2,1,2,3,4,6,5,3,2,1というデータが得られます。
このサイクルを何千回と止めずに繰り返します。そうするとデータとしてはサイクルごとではなく全サイクルつながってでてきます。
なので列の上から順におっていき数値が下りはじめるところ(上の例では5)を1サイクル目の最大値、そして上がりはじめるところ(上の例では1)を最小値として抜き出しこれを1サイクルとして2サイクル目、3サイクル目・・と抜き出していきます(2サイクル目では6と1)。

よって出力したものにはサイクル数とそれに応じた最大値最小値が表示されます。
というか下がり始める所と上がり始める所を抜き出してそれにサイクル数をふっていくって感じです。

それでその抜き出した最大最小値と同じ行のB列の値も一緒に抜き出したいということです。


この説明でだいじょぶでしょうか。

何度も本当に申し訳ありません。よろしくお願いします。

【50133】Re:データ整理
発言  ichinose  - 07/7/10(火) 20:38 -

引用なし
パスワード
   ▼林 さん:
こんばんは。

>
>私はプログラミングとはまったく違う分野のものでしてこのコードも私が作ったものではなく前に作られたものなんです。
>
>自分で勉強すればいいって話なんですが
本来は、そうですし、ここはそういう方が対象のサイトですよね!!

>
>それで定義なんですが、
>
>金属をとある装置で引っ張って縮める、引っ張って縮める・・・と繰り返す実験を行います。その引っ張って縮めるまでを1サイクルとすると1,2,3,4,5,4,2,1というデータが得られるとします。縮め終えたらまた引っ張って縮める。これで2サイクルです。データとしては1サイクル目とあわせて1,2,3,4,5,4,2,1,2,3,4,6,5,3,2,1というデータが得られます。
>このサイクルを何千回と止めずに繰り返します。そうするとデータとしてはサイクルごとではなく全サイクルつながってでてきます。
>なので列の上から順におっていき数値が下りはじめるところ(上の例では5)を1サイクル目の最大値、そして上がりはじめるところ(上の例では1)を最小値として抜き出しこれを1サイクルとして2サイクル目、3サイクル目・・と抜き出していきます(2サイクル目では6と1)。
>
>よって出力したものにはサイクル数とそれに応じた最大値最小値が表示されます。
>というか下がり始める所と上がり始める所を抜き出してそれにサイクル数をふっていくって感じです。
>
>それでその抜き出した最大最小値と同じ行のB列の値も一緒に抜き出したいということです。
>
>
>この説明でだいじょぶでしょうか。
まだわかりません。

(1)

1,2,3,4,5,4,2,1,2,3,4,6,5,3,2,1というデータをシートStress_DataのA列に
設定して
林さんが提示されたコードを実行すると、

シートCycle_vs_MaxSgには、

Cycle   Max_Stress   Min_Stress
 1      5        2

という結果になりますが、正しいのですか?

(2)

1,2,3,4,5,4,3,2,1,0.5,1,2,3,2,1というデータをシートStress_DataのA列に

設定して
林さんが提示されたコードを実行すると、

シートCycle_vs_MaxSgには、

Cycle    Max_Stress    Min_Stress
1      5         0.5

という結果になりますが、正しいのですか?

(3)

1,2,3,4,5,5,4,3,2,1,0.5,1,2,3,4,5,4,3,2,1 というデータをシートStress_DataのA列に

設定して
林さんが提示されたコードを実行すると、

シートCycle_vs_MaxSgには、

Cycle    Max_Stress    Min_Stress
1      5         0.5

という結果になりますが、正しいのですか?


正しくないのであれば、正しい結果を記述してください。


提示されたコードで最大値・最小値が正しく取得できていない

と私は思っているのですが、いかがですか?

沢山の例を出していただかないと規則性がわかりませんよ!!

前にも同じ事をどこかで記述しましたが、高校生の等差数列だって
規則性を見つけるのに3つぐらいの例が必要です。

もっと難しいことをプログラミングするのなら
それ相応の例を用意してください。

【50138】Re:データ整理
発言  Lindy  - 07/7/11(水) 10:15 -

引用なし
パスワード
   ▼林 さん:
こんにちは。

振っておきながら忙しくて見られませんでした。

ichinoseさんも仰られていますが、同じ理由で林さんのコードは解読してません。

あとはB列のデータも何が入っているのかわからないです。
(なので変数はVariantです。)

だいたい、こんな感じの事をしたいのでしょうか?
(もっとスマートに組めそうな気もしますが・・・私の能力限界)

Option Explicit
Option Base 1
Sub test()
Dim stdat() As Variant, cydat() As Variant, lndat As Long, i As Long
With ThisWorkbook
 With .Sheets("Stress_Data")
  lndat = .Cells(.Rows.Count, 1).End(xlUp).Row
  stdat = .Range("A1", .Cells(lndat, 2)).Value
 End With
 ReDim cydat(5, 1)
 For i = 2 To UBound(stdat) - 1
  If stdat(i, 1) > stdat(i - 1, 1) And _
    stdat(i, 1) > stdat(i + 1, 1) Then
   ReDim Preserve cydat(5, UBound(cydat, 2) + 1)
   cydat(1, UBound(cydat, 2)) = UBound(cydat, 2) - 1
   cydat(2, UBound(cydat, 2)) = stdat(i, 1)
   cydat(4, UBound(cydat, 2)) = stdat(i, 2)
  ElseIf stdat(i, 1) < stdat(i - 1, 1) And _
      stdat(i, 1) < stdat(i + 1, 1) Then
   cydat(3, UBound(cydat, 2)) = stdat(i, 1)
   cydat(5, UBound(cydat, 2)) = stdat(i, 2)
  End If
 Next i
 cydat(3, UBound(cydat, 2)) = stdat(i, 1)
 cydat(5, UBound(cydat, 2)) = stdat(i, 2)
 With .Sheets("Cycle_vs_MaxSg")
  .Columns("A:E").ClearContents
  .Range("A1").Resize(UBound(cydat, 2), 5).Value = _
   Application.Transpose(cydat)
  .Range("A1:E1").Value = _
   Array("Cycle", "Max_Stress", "Min_Stress", "Max_ColB", "Min_ColB")
 End With
End With
End Sub

>>自分で勉強すればいいって話なんですが
>本来は、そうですし、ここはそういう方が対象のサイトですよね!!

に、同感なのであえて説明はつけていません。
少し見てみてくださ〜い^^

これ、コードの解読や記述が御自分でも出来ないと
実験データの信憑性を疑われた時に困ってしまうと思うので
仮に出来たとしても、しっかり理解された方が良いですよ?

【50143】Re:データ整理
お礼    - 07/7/11(水) 12:02 -

引用なし
パスワード
   ▼ichinoseさん Lindy さん:
いろいろとすみません。
時間できたら勉強してみようと思います。
それが一番ですね。

とりあえずお二方のを参考にがんばってみます。

ありがとうございました。

5561 / 13645 ツリー ←次へ | 前へ→
ページ:  ┃  記事番号:
2610219
(SS)C-BOARD v3.8 is Free