Excel VBA質問箱 IV

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

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


5194 / 13644 ツリー ←次へ | 前へ→

【52108】各要素に各弾性係数を与えて計算する方法について ちゃや 07/10/21(日) 14:41 質問[未読]
【52109】Re:各要素に各弾性係数を与えて計算する方... ちゃや 07/10/21(日) 14:42 質問[未読]
【52110】Re:各要素に各弾性係数を与えて計算する方... りん 07/10/21(日) 15:11 発言[未読]
【52118】Re:各要素に各弾性係数を与えて計算する方... ちゃや 07/10/22(月) 7:07 質問[未読]
【52131】Re:各要素に各弾性係数を与えて計算する方... りん 07/10/22(月) 19:29 回答[未読]
【52158】Re:各要素に各弾性係数を与えて計算する方... ちゃや 07/10/25(木) 17:30 お礼[未読]

【52108】各要素に各弾性係数を与えて計算する方法...
質問  ちゃや  - 07/10/21(日) 14:41 -

引用なし
パスワード
   エクセルのシートが、Worksheets(入力1)、(入力2)、(出力)の三枚あり、三枚目の出力のシートに計算というコマンドをつくりそこに以下のようなコードを記しています。
入力1のシートには、
二次元弾性解析(入力1)                                
                                
弾性係数        ポアソン比    計算フラグ(0(平面応力) / 1(平面ひず                               み) で指定)                
2.10E+04        0.3        0                

節点の数                要素の数                
18                22                

番号    座標X    座標X        番号    節点1    節点2    節点3    
1    0    0        1    1    2    5    
2    40    0        2    1    5    4    
3    60    0        3    2    6    5    
4    0    40        4    2    3    6    
5    40    40        5    3    7    6    
6    60    20        6    5    6    8    
7    80    20        7    6    9    8    
8    60    40        8    6    7    9    
9    80    40        9    7    10    9    
10    100    40        10    4    12    11    
11    0    60        11    4    5    12    
12    40    60        12    5    13    12    
13    60    60        13    5    8    13    
14    100    60        14    8    9    13    
15    0    100        15    9    14    13    
16    40    100        16    9    10    14    
17    60    100        17    11    16    15    
18    100    100        18    11    12    16    
                19    12    17    16    
                20    12    13    17    
                21    13    18    17    
                22    13    14    18


入力2のシートには
二次元弾性解析(入力2)                

荷重の数            拘束の数    
4            7    

Y方向はマイナス            Y方向はマイナス    
節点番号    荷重        節点番号    拘束変位
-15    20        1    0
-16    30        -1    0
-17    30        -2    0
-18    20        -3    0
            4    0
            11    0
            15    0
出力シートには
二次元弾性解析(計算・出力)


変位                反力            歪み                    応力            
節点    X    Y        節点    反力        要素    εx    εy    εz    γxy    σx    σy    σz    γxy

があり、またコマンドボタンがひとつあります。それをクリックすると以下のプログラムが実行されます。

コードはデータ入力(計算フラグ)・ バンド幅計算(バンド幅)・ 剛性行列(バンド幅, 計算フラグ)・境界・連立計算(バンド幅)・結果(計算フラグ)・結果出力の7個から構成されています。データ入力(計算フラグ)では、入力1,入力2のシートの値を読み込んでいます。そして剛性行列では、aSub(三角形要素面積の計算),bSub(3×6の行列の各成分),dSub(3×3の行列の各成分),tSub(要素剛性行列の計算)を使って、8×8の全体剛性行列をつくっています。その行列に境界を代入して、連立計算で未知数を求めていきます。求めた未知数を式に代入して、結果が得られます。それを結果出力で出力シートに表示させます。

そのようなコードの中で、入力1のシートによって弾性係数がひとつ与えられているのですが、それを各要素によってそれぞれ変えて与えたいと考えています。そこで、弾性係数を読み取るときに
Const Max要素=200
Dim 弾性係数(Max要素)
弾性係数(i)=Range("_弾性係数").OFFSET(I,0)
としたのですが、結局一番最後の要素番号の弾性係数の値ですべて計算されてしまい、うまくいきません。どうしたら、各要素に与えられた弾性係数でこのプログラムの計算を無事に終えることができるでしょうか??よろしくお願いします。

Private Sub CommandButton1_Click()

  Dim 計算フラグ, バンド幅

  Call データ入力(計算フラグ)
  Call バンド幅計算(バンド幅)
  Call 剛性行列(バンド幅, 計算フラグ)
  Call 境界
  Call 連立計算(バンド幅)
  Call 結果(計算フラグ)
  Call 結果出力

End Sub

Private Sub データ入力(計算フラグ)

  Dim I
  
  With Worksheets(入力シート名1)
    計算フラグ = .Range("_計算フラグ")
    弾性係数 = .Range("_弾性係数")
    ポアソン比 = .Range("_ポアソン比")
    節点の数 = .Range("_節点の数")
    For I = 1 To 節点の数
      座標(I) = .Range("_座標X").Offset(I, 0)
      座標(節点の数 + I) = .Range("_座標Y").Offset(I, 0)
    Next I
    要素の数 = .Range("_要素の数")
    For I = 1 To 要素の数
      要素節点(I, 1) = .Range("_要素節点1").Offset(I, 0)
      要素節点(I, 2) = .Range("_要素節点2").Offset(I, 0)
      要素節点(I, 3) = .Range("_要素節点3").Offset(I, 0)
    Next I
  End With
  With Worksheets(入力シート名2)
    荷重の数 = .Range("_荷重の数")
    For I = 1 To 荷重の数
      荷重節点(I) = .Range("_荷重節点").Offset(I, 0)
      荷重(I) = .Range("_荷重").Offset(I, 0)
    Next I
    拘束の数 = .Range("_拘束の数")
    For I = 1 To 拘束の数
      拘束節点(I) = .Range("_拘束節点").Offset(I, 0)
      拘束変位(I) = .Range("_拘束変位").Offset(I, 0)
    Next I
  End With

End Sub

Private Sub バンド幅計算(バンド幅)

  Dim J, M, Imin, Imax

  バンド幅 = 0
  For J = 1 To 節点の数
    Kanl(2 * J - 1) = J
    Kanl(2 * J) = J + 節点の数
  Next J
  For M = 1 To 要素の数
    Imin = 要素節点(M, 1)
    Imax = 要素節点(M, 1)
    For J = 2 To 3
      If Imin > 要素節点(M, J) Then Imin = 要素節点(M, J)
      If Imax < 要素節点(M, J) Then Imax = 要素節点(M, J)
    Next J
    If Imax - Imin > バンド幅 Then バンド幅 = Imax - Imin
  Next M
  バンド幅 = 2 * (バンド幅 + 1)
  If (バンド幅 > MAXバンド幅) Then
    MsgBox "計算メモリオーバー", vbCritical + vbOKOnly
    End
  End If

End Sub

Private Sub 剛性行列(バンド幅, 計算フラグ)
  
  Dim I, J, M, Ix, Iy, Jx, Jy, Kx, Ky, K, Tt, S
  Dim bb(3, 6), sds(3, 3)

  For I = 1 To 2 * 節点の数
    For J = 1 To バンド幅
      Syk(I, J) = 0#
      Tky(I, J) = 0#
    Next J
  Next I
  For M = 1 To 要素の数
    Call aSub(M, Ix, Iy, Jx, Jy, Kx, Ky, S)
    Call bSub(Ix, Iy, Jx, Jy, Kx, Ky, S)
    Call dSub(計算フラグ)
    For J = 1 To 3
      For I = 1 To 3
        sds(I, J) = S * Dsep(I, J)
      Next I
    Next J
    For I = 1 To 3
      For K = 1 To 6
        Tt = 0#
        For J = 1 To 3
          Tt = Tt + sds(I, J) * B(J, K)
        Next J
        bb(I, K) = Tt
      Next K
    Next I
    For I = 1 To 6
      For K = 1 To 6
        Tt = 0#
        For J = 1 To 3
          Tt = Tt + B(J, I) * bb(J, K)
        Next J
        elk(I, K) = Tt
      Next K
    Next I
    Call tSub(Ix, Iy, Jx, Jy, Kx, Ky)
  Next M
  For I = 1 To MAX要素
    For J = 1 To MAXバンド幅
      Tky(I, J) = Syk(I, J)
    Next J
  Next I

End Sub

【52109】Re:各要素に各弾性係数を与えて計算する...
質問  ちゃや  - 07/10/21(日) 14:42 -

引用なし
パスワード
  
さきほどのプログラムの続きです。

Private Sub aSub(M, Ix, Iy, Jx, Jy, Kx, Ky, S)

  Dim S1, S2

  Ix = 要素節点(M, 1)
  Iy = Ix + 節点の数
  Jx = 要素節点(M, 2)
  Jy = Jx + 節点の数
  Kx = 要素節点(M, 3)
  Ky = Kx + 節点の数
  S1 = 座標(Jx) * 座標(Ky) + 座標(Kx) * 座標(Iy) _
      + 座標(Ix) * 座標(Jy)
  S2 = 座標(Kx) * 座標(Jy) + 座標(Ix) * 座標(Ky) _
      + 座標(Jx) * 座標(Iy)
  S = 0.5 * (S1 - S2)

End Sub

Private Sub bSub(Ix, Iy, Jx, Jy, Kx, Ky, S)
  
  B(1, 1) = 0.5 * (座標(Jy) - 座標(Ky)) / S
  B(2, 1) = 0#
  B(3, 1) = 0.5 * (座標(Kx) - 座標(Jx)) / S
  B(1, 2) = 0.5 * (座標(Ky) - 座標(Iy)) / S
  B(2, 2) = 0#
  B(3, 2) = 0.5 * (座標(Ix) - 座標(Kx)) / S
  B(1, 3) = 0.5 * (座標(Iy) - 座標(Jy)) / S
  B(2, 3) = 0#
  B(3, 3) = 0.5 * (座標(Jx) - 座標(Ix)) / S
  B(1, 4) = 0#
  B(2, 4) = 0.5 * (座標(Kx) - 座標(Jx)) / S
  B(3, 4) = 0.5 * (座標(Jy) - 座標(Ky)) / S
  B(1, 5) = 0#
  B(2, 5) = 0.5 * (座標(Ix) - 座標(Kx)) / S
  B(3, 5) = 0.5 * (座標(Ky) - 座標(Iy)) / S
  B(1, 6) = 0#
  B(2, 6) = 0.5 * (座標(Jx) - 座標(Ix)) / S
  B(3, 6) = 0.5 * (座標(Iy) - 座標(Jy)) / S

End Sub

Private Sub dSub(計算フラグ)

  Dim R

  If 計算フラグ <> 1 Then
    R = 弾性係数 / (1# - ポアソン比 ^ 2)
    Dsep(1, 1) = R
    Dsep(2, 1) = R * ポアソン比
    Dsep(3, 1) = 0#
    Dsep(1, 2) = Dsep(2, 1)
    Dsep(2, 2) = R
    Dsep(3, 2) = 0#
    Dsep(1, 3) = 0#
    Dsep(2, 3) = 0#
    Dsep(3, 3) = 0.5 * R * (1# - ポアソン比)
  Else
    R = 弾性係数 * (1# - ポアソン比) _
        / (1# + ポアソン比) / (1# - 2# * ポアソン比)
    Dsep(1, 1) = R
    Dsep(2, 1) = R * ポアソン比 / (1# - ポアソン比)
    Dsep(3, 1) = 0#
    Dsep(1, 2) = Dsep(2, 1)
    Dsep(2, 2) = R
    Dsep(3, 2) = 0#
    Dsep(1, 3) = 0#
    Dsep(2, 3) = 0#
    Dsep(3, 3) = 0.5 * 弾性係数 / (1# + ポアソン比)
  End If

End Sub

Private Sub tSub(Ix, Iy, Jx, Jy, Kx, Ky)

  Dim I, J, Ixj, Jxj, Kxj, Iyj, Jyj, Kyj, It, Jt

  For J = 1 To 2 * 節点の数
    If (Kanl(J) = Ix) Then Ixj = J
    If (Kanl(J) = Jx) Then Jxj = J
    If (Kanl(J) = Kx) Then Kxj = J
    If (Kanl(J) = Iy) Then Iyj = J
    If (Kanl(J) = Jy) Then Jyj = J
    If (Kanl(J) = Ky) Then Kyj = J
  Next J
  For I = 1 To 6
    If (I = 1) Then It = Ixj
    If (I = 2) Then It = Jxj
    If (I = 3) Then It = Kxj
    If (I = 4) Then It = Iyj
    If (I = 5) Then It = Jyj
    If (I = 6) Then It = Kyj
    For J = 1 To 6
      If (J = 1) Then Jt = Ixj
      If (J = 2) Then Jt = Jxj
      If (J = 3) Then Jt = Kxj
      If (J = 4) Then Jt = Iyj
      If (J = 5) Then Jt = Jyj
      If (J = 6) Then Jt = Kyj
      If (It <= Jt) Then
        Syk(It, Jt - It + 1) = Syk(It, Jt - It + 1) _
            + elk(I, J)
      End If
    Next J
  Next I

End Sub

Private Sub 境界()

  Dim N, I, K, L

  N = 2 * 節点の数
  For I = 1 To N
    反力(I) = 0#
  Next I
  For K = 1 To N
    For I = 1 To 拘束の数
      L = 拘束節点(I)
      If (L < 0) Then L = 節点の数 - L
      If (Kanl(K) = L) Then
        Syk(K, 1) = 10000000000# * Syk(K, 1)
        反力(K) = Syk(K, 1) * 拘束変位(I)
        Exit For
      End If
    Next I
  Next K
  If (荷重の数 > 0) Then
    For K = 1 To N
      For I = 1 To 荷重の数
        L = 荷重節点(I)
        If (L < 0) Then L = 節点の数 - L
        If (Kanl(K) = L) Then 反力(K) = 荷重(I)
      Next I
    Next K
  End If

End Sub

Private Sub 連立計算(バンド幅)

  Dim I, J, L, N, S
  Dim Ik(MAX節点), Jk(MAX節点)

  N = 2 * 節点の数
  For I = 1 To バンド幅
    Ik(I) = 1
  Next I
  For I = バンド幅 + 1 To N
    Ik(I) = I - バンド幅 + 1
  Next I
  For J = 1 To N - バンド幅
    Jk(J) = J + バンド幅 - 1
  Next J
  For J = N - バンド幅 + 1 To N
    Jk(J) = N
  Next J
  For J = 2 To Jk(1)
    Syk(1, J) = Syk(1, J) / Syk(1, 1)
  Next J
  For I = 2 To N
    S = 0#
    For L = Ik(I) To I - 1
      S = S + Syk(L, I - L + 1) _
          * Syk(L, I - L + 1) * Syk(L, 1)
    Next L
    Syk(I, 1) = Syk(I, 1) - S
    If (I <> N) Then
      For J = I + 1 To Jk(I)
        S = 0#
        If (I >= N - バンド幅 + 2 Or J <> Jk(I)) Then
          For L = Ik(J) To I - 1
            S = S + Syk(L, I - L + 1) _
                * Syk(L, J - L + 1) * Syk(L, 1)
          Next L
        End If
        Syk(I, J - I + 1) = (Syk(I, J - I + 1) - S) _
                    / Syk(I, 1)
      Next J
    End If
  Next I
  For I = 2 To N
    S = 0#
    For J = Ik(I) To I - 1
      S = S + Syk(J, I - J + 1) * 反力(J)
    Next J
    反力(I) = 反力(I) - S
  Next I
  For L = 1 To N
    I = N - L + 1
    S = 0#
    If (I <> N) Then
      For J = I + 1 To Jk(I)
        S = S + Syk(I, J - I + 1) * 変位(J)
      Next J
    End If
    変位(I) = 反力(I) / Syk(I, 1) - S
  Next L
  For I = 1 To MAX要素
    For J = 1 To MAXバンド幅
      Syk(I, J) = Tky(I, J)
    Next J
  Next I
  For I = 1 To N
    S = 0#
    If (I <> N) Then
      For J = I + 1 To Jk(I)
        S = S + Syk(I, J - I + 1) * 変位(J)
      Next J
    End If
    For J = Ik(I) To I
      S = S + Syk(J, I - J + 1) * 変位(J)
    Next J
    反力(I) = S
  Next I
  For I = 1 To 節点の数
    J = I + 節点の数
    Syk(I, 1) = 変位(2 * I - 1)
    Syk(J, 1) = 変位(2 * I)
  Next I
  For I = 1 To N
    変位(I) = Syk(I, 1)
  Next I

End Sub

Private Sub 結果(計算フラグ)

  Dim M, Ix, Iy, Jx, Jy, Kx, Ky
  Dim S, Epsx, Epsy, Gaxy1, Gaxy2, Gaxy

  For M = 1 To 要素の数
    Call aSub(M, Ix, Iy, Jx, Jy, Kx, Ky, S)
    Call bSub(Ix, Iy, Jx, Jy, Kx, Ky, S)
    Call dSub(計算フラグ)
    Epsx = B(1, 1) * 変位(Ix) + B(1, 2) * 変位(Jx) _
        + B(1, 3) * 変位(Kx)
    Epsy = B(2, 4) * 変位(Iy) + B(2, 5) * 変位(Jy) _
        + B(2, 6) * 変位(Ky)
    Gaxy1 = B(3, 1) * 変位(Ix) + B(3, 2) * 変位(Jx) _
        + B(3, 3) * 変位(Kx)
    Gaxy2 = B(3, 4) * 変位(Iy) + B(3, 5) * 変位(Jy) _
        + B(3, 6) * 変位(Ky)
    Gaxy = Gaxy1 + Gaxy2
    歪み(M, 1) = Epsx
    歪み(M, 2) = Epsy
    Gxy(M) = Gaxy
    応力(M, 1) = Dsep(1, 1) * Epsx + Dsep(1, 2) * Epsy _
          + Dsep(1, 3) * Gaxy
    応力(M, 2) = Dsep(2, 1) * Epsx + Dsep(2, 2) * Epsy _
          + Dsep(2, 3) * Gaxy
    tauxy(M) = Dsep(3, 1) * Epsx + Dsep(3, 2) * Epsy _
          + Dsep(3, 3) * Gaxy
    If (計算フラグ <> 1) Then
      応力(M, 3) = 0#
      歪み(M, 3) = (1# - 2# * ポアソン比) / (弾性係数 _
          * (応力(M, 1) + 応力(M, 2))) - (Epsx + Epsy)
    Else
      応力(M, 3) = ポアソン比 * (応力(M, 1) + 応力(M, 2))
      歪み(M, 3) = 0#
    End If
  Next M

End Sub

Private Sub 結果出力()

  Dim I, M

  With Worksheets(出力シート名)
    For I = 1 To 節点の数
      .Range("_節点番号").Offset(I, 0) = I
      .Range("_変位X").Offset(I, 0) = 変位(I)
      .Range("_変位Y").Offset(I, 0) = 変位(節点の数 + I)
    Next I
    For I = 1 To 拘束の数
      If (拘束節点(I) > 0) Then
        M = 2 * 拘束節点(I) - 1
      Else
        M = 2 * -拘束節点(I)
      End If
      .Range("_反力節点").Offset(I, 0) = 拘束節点(I)
      .Range("_反力").Offset(I, 0) = 反力(M)
    Next I
  
    For I = 1 To 要素の数
      .Range("_要素番号").Offset(I, 0) = I
      .Range("_歪みX").Offset(I, 0) = 歪み(I, 1)
      .Range("_歪みY").Offset(I, 0) = 歪み(I, 2)
      .Range("_歪みZ").Offset(I, 0) = 歪み(I, 3)
      .Range("_歪みXY").Offset(I, 0) = Gxy(I)
      .Range("_応力X").Offset(I, 0) = 応力(I, 1)
      .Range("_応力Y").Offset(I, 0) = 応力(I, 2)
      .Range("_応力Z").Offset(I, 0) = 応力(I, 3)
      .Range("_応力XY").Offset(I, 0) = tauxy(I)
    Next I
  End With

End Sub

【52110】Re:各要素に各弾性係数を与えて計算する...
発言  りん E-MAIL  - 07/10/21(日) 15:11 -

引用なし
パスワード
   ちゃや さん、こんにちわ。

>Dim 弾性係数(Max要素)
>弾性係数(i)=Range("_弾性係数").OFFSET(I,0)
>としたのですが、結局一番最後の要素番号の弾性係数の値ですべて計算されてしま



>    弾性係数 = .Range("_弾性係数")

たくさん書かれていますが、現在書いてあるコードではそうしてないようですが。

【52118】Re:各要素に各弾性係数を与えて計算する...
質問  ちゃや  - 07/10/22(月) 7:07 -

引用なし
パスワード
   りんさん返信ありがとうございます!

すみません。乗せていたコードを

Dim 弾性係数(Max要素)
弾性係数(i)=Range("_弾性係数").OFFSET(I,0)

のように修正していませんでした。

今もともとあまりVBAの知識がない中で、プログラムをやっていて、明らかに自分の力量ではやろうとしていることには程遠い状態です。有料でもいいのでこの質問にたいしてどこか教えてくれるところはないでしょうか??このような失礼な発言をどうか許してください。

りんさん、長い書き込み読んでくだっさってありがとうございました。

【52131】Re:各要素に各弾性係数を与えて計算する...
回答  りん E-MAIL  - 07/10/22(月) 19:29 -

引用なし
パスワード
   ちゃや さん、こんばんわ。

>すみません。乗せていたコードを
>Dim 弾性係数(Max要素)
>弾性係数(i)=Range("_弾性係数").OFFSET(I,0)
>のように修正していませんでした。
なおして試したコードを張ってほしかったんですけどね。

とりあえず、弾性係数に関連した部分に修正を入れてみました。

'/////////////////////// 要素ごとに読み込むためにループに入れる
Private Sub データ入力(計算フラグ)
=========略=========
    For I = 1 To 要素の数
      要素節点(I, 1) = .Range("_要素節点1").Offset(I, 0)
      要素節点(I, 2) = .Range("_要素節点2").Offset(I, 0)
      要素節点(I, 3) = .Range("_要素節点3").Offset(I, 0)
      弾性係数(I) = .Range("_弾性係数").Offset(I, 0)
    Next I
  End With
=========略=========
End Sub
'/////////////////////// Callする時の引数の数が変更
Private Sub 剛性行列(バンド幅, 計算フラグ)
=========略=========
    Call dSub(計算フラグ, M)
=========略=========
End Sub
'/////////////////////// 要素番号を渡す、弾性係数も配列
Private Sub dSub(計算フラグ, M)
=========略=========
    R = 弾性係数(M) / (1# - ポアソン比 ^ 2)
=========略=========
    R = 弾性係数(M) * (1# - ポアソン比) _
        / (1# + ポアソン比) / (1# - 2# * ポアソン比)
=========略=========
    Dsep(3, 3) = 0.5 * 弾性係数(M) / (1# + ポアソン比)
=========略=========
End Sub
'/////////////////////// Callする時の引数の数が変更、弾性係数も配列
Private Sub 結果(計算フラグ)
=========略=========
    Call dSub(計算フラグ, M)
=========略=========
      歪み(M, 3) = (1# - 2# * ポアソン比) / (弾性係数(M) _
          * (応力(M, 1) + 応力(M, 2))) - (Epsx + Epsy)
=========略=========
End Sub

こんな感じです。
有料な教室はいろいろあるとおもいますけど、私は知らないのでごめんなさい。

【52158】Re:各要素に各弾性係数を与えて計算する...
お礼  ちゃや  - 07/10/25(木) 17:30 -

引用なし
パスワード
   ▼りん さん:
本当にありがとうございます!
本当に本当に助かりました!!
ありがとうございました!!!!

せっかく教えてもらったのに、自分のミスでうまくできずにこんなに返事が遅れてしまい申し訳ありませんでした。

結果、問題なく計算することができました!!

ありがとうございます。

これからも勉強がんばります!

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

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