Excel VBA質問箱 IV

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

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


4733 / 13646 ツリー ←次へ | 前へ→

【54674】転記したワークシートのデーターをユーザーフォームで閲覧する Regina 08/3/25(火) 22:25 質問[未読]
【54693】Re:転記したワークシートのデーターをユー... VBWASURETA 08/3/26(水) 13:20 質問[未読]
【54704】Re:転記したワークシートのデーターをユー... Regina 08/3/26(水) 19:50 発言[未読]
【54705】Re:転記したワークシートのデーターをユー... Regina 08/3/26(水) 20:00 発言[未読]
【54711】Re:転記したワークシートのデーターをユー... VBWASURETA 08/3/27(木) 12:26 質問[未読]
【54733】Re:転記したワークシートのデーターをユー... Regina 08/3/27(木) 22:57 発言[未読]
【54735】Re:転記したワークシートのデーターをユー... VBWASURETA 08/3/28(金) 2:13 質問[未読]
【54736】Re:転記したワークシートのデーターをユー... Regina 08/3/28(金) 7:14 発言[未読]
【54737】Re:転記したワークシートのデーターをユー... VBWASURETA 08/3/28(金) 9:09 回答[未読]
【54774】Re:転記したワークシートのデーターをユー... Regina 08/3/29(土) 11:04 発言[未読]
【54776】Re:転記したワークシートのデーターをユー... ツル 08/3/29(土) 13:01 回答[未読]
【54785】Re:転記したワークシートのデーターをユー... Regina 08/3/30(日) 0:26 発言[未読]
【54786】Re:転記したワークシートのデーターをユー... Hirofumi 08/3/30(日) 0:56 回答[未読]
【54794】Re:転記したワークシートのデーターをユー... Regina 08/3/30(日) 13:24 発言[未読]
【54795】Re:転記したワークシートのデーターをユー... Hirofumi 08/3/30(日) 13:37 回答[未読]
【54803】Re:転記したワークシートのデーターをユー... Regina 08/3/30(日) 22:27 発言[未読]
【54817】Re:転記したワークシートのデーターをユー... VBWASURETA 08/3/31(月) 15:08 発言[未読]
【54823】Re:転記したワークシートのデーターをユー... Hirofumi 08/3/31(月) 18:13 回答[未読]
【54825】Re:転記したワークシートのデーターをユー... Hirofumi 08/3/31(月) 20:33 回答[未読]
【54826】Re:転記したワークシートのデーターをユー... Hirofumi 08/3/31(月) 21:30 回答[未読]
【54827】Re:転記したワークシートのデーターをユー... Regina 08/3/31(月) 22:30 発言[未読]
【54830】Re:転記したワークシートのデーターをユー... VBWASURETA 08/4/1(火) 9:55 発言[未読]
【54843】Re:転記したワークシートのデーターをユー... Regina 08/4/1(火) 16:08 発言[未読]
【54844】Re:転記したワークシートのデーターをユー... VBWASURETA 08/4/1(火) 16:51 発言[未読]
【54847】Re:転記したワークシートのデーターをユー... わさび 08/4/1(火) 18:29 発言[未読]
【54848】Re:転記したワークシートのデーターをユー... Hirofumi 08/4/1(火) 19:15 回答[未読]
【54849】Re:転記したワークシートのデーターをユー... Hirofumi 08/4/1(火) 19:34 回答[未読]
【54850】Re:転記したワークシートのデーターをユー... Regina 08/4/1(火) 23:12 発言[未読]
【54873】Re:転記したワークシートのデーターをユー... Hirofumi 08/4/2(水) 19:17 回答[未読]
【54877】Re:転記したワークシートのデーターをユー... Regina 08/4/3(木) 0:14 お礼[未読]

【54674】転記したワークシートのデーターをユーザ...
質問  Regina  - 08/3/25(火) 22:25 -

引用なし
パスワード
   最近、ここでお世話になっています。VBA初心者です。
ユーザーフォームで入力したデーターをワークシートに転記しています。
そのデーターを閲覧するのに、ユーザーフォームで表示できるようにしたいと思い、本をまねてコードを入力しました。

新規登録はUserForm3を表示し、データー閲覧はUserForm4を表示するように、ワークシートのボタンに設定しています。

ワークシート名:データーベース
   入力データー名:患者ID
           氏名
           性別
           生年月日
           年齢
           入院・外来
           発症日・起算日
           主治医・処方医
           診断名
           種別
           算定期限
           転機
   新規登録ボタン:クリックするとデーター入力用のユーザーフォームを表示
          (ユーザーフォーム名:UserForm3)
   データー閲覧ボタン:データー閲覧用のユーザーフォームを表示
          (ユーザーフォーム名:UserForm4)

UserForm4:
 患者ID→TextBox1 氏名→TextBOx2 
 性別→Frame8内に「男」はOptionButton1、「女」はOptionButton2
 生年月日→TextBox3 年齢→TextBox4 
 入院・外来→Frame2内に「入院」はOptionButton3、「外来」はOptionButton4
 入院日→TextBox5 診断名→TextBox6 主治医・処方医→TextBox9
 種別→Frame9内に CheckBox1〜CheckBox8まで
 発症日・起算日→TextBox7 算定期限日→TextBox8
 転機→Frame10内にCheckBox9〜CheckBox12
 <前 →CommandButton9  次> →CommandButton10
 閉じる →CommandButton11

以下の、コードは行の取得が上手くいくか分からなかったので、TextBox1(患者ID)とTextBox2(氏名)とOptionButton1・2(男性・女性の選択)だけ、始めに設定しようと思って試しにしてみました。[Database]はワークシート(名:データーベース)のデーター入力部分5行分と名前(患者IDや氏名・性別と書いてある部分)を選択した範囲の名前です。下記を入力後、実行をクリックしましたが、特にコード中には問題はなかったです(赤くなっていたり、黄色になっていませんでした)。しかし、データー閲覧のユーザーフォームには、患者IDや氏名や性別の表示が出来ていませんでした。COUNT関数とCallステートメントの入力がおかしいでしょうか?ご教授お願い致します。
-------------------------------------------------------------------

Dim 表示行 As Long
Dim 最終行 As Long
Option Explicit
Private Sub UserForm4_Initialize()
 表示行 = 2  →先頭レコードが2行目からなので、表示行には2を代入
 最終行 = WorksheetFunction.CountA([Database].Resize(, 1))
        →COUNT関数を使って、左端列の行数を数えて代入
 Call データー表示
End Sub
Private Sub CommandButton9_Click()
 If 最終行 <= 2 Then
   Beep
 Else
   表示行 = 表示行 - 1
   Call データー表示
 End If
 
End Sub
Private Sub CommandButton10_Click()
 If 最終行 >= 最終行 Then
   Beep
 Else
   表示行 = 表示行 + 1
   Call データー表示
 End If
 
End Sub
Private Sub CommandButton11_Click()
 Unload UserForm4
End Sub
Private Sub データー表示()
 TextBox1 = [Database].Cells(表示行, 1)
 TextBox2 = [Database].Cells(表示行, 2)
 
 If [Datebase].Cells(表示行, 3) = "男性" Then
  OptionButton1.Value = True
 Else
  OptionButton2.Value = True
 End If
 
End Sub
---------------------------------------------------------------------

【54693】Re:転記したワークシートのデーターをユ...
質問  VBWASURETA  - 08/3/26(水) 13:20 -

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

あまりきっちり見てませんが
気になった点について書きますね。


> If 最終行 <= 2 Then

ですが、2行目からデータがあるのですよね?
この条件だと2行目無視しますよ?


> If 最終行 >= 最終行 Then

次にこれは常に最終行なので真の条件(無視条件)ですよね?


> TextBox1 = [Database].Cells(表示行, 1)
> TextBox2 = [Database].Cells(表示行, 2)

最後にこの[Database]指定はSheets(シート名)なのでしょうか?

【54704】Re:転記したワークシートのデーターをユ...
発言  Regina  - 08/3/26(水) 19:50 -

引用なし
パスワード
   ▼VBWASURETA さん:
ご指摘ありがとうございます。

If 最終行 <= 2 Then を

If 表示行 <= 2 Then にしてみます。

If 最終行 >= 最終行 Then を

If 表示行 >= 最終行 Then  にしてみます。


>> TextBox1 = [Database].Cells(表示行, 1)
>> TextBox2 = [Database].Cells(表示行, 2)
>
>最後にこの[Database]指定はSheets(シート名)なのでしょうか?

ワークシート上のデーター入力済み範囲の名前です。
入力している5件分のレコードの範囲と、名前(患者IDや氏名などが記載されている一番上の部分)の範囲の部分です。
-------------------------------------------------------------------- 
     患者ID  氏名   性別  生年月日    年齢  …
--------------------------------------------------------------------
  1  12345  山田   男性 昭和○○年○月○日  26
  2    …    …    …    …         …     
  3    …    …    …    …         …
  4    …    …    …    …         …
  5    …    …    …    …         …

---------------------------------------------------------------------
上記のようなデーターの部分を範囲指定して[Database]という名前にしています。

【54705】Re:転記したワークシートのデーターをユ...
発言  Regina  - 08/3/26(水) 20:00 -

引用なし
パスワード
   >If 最終行 <= 2 Then を
>
>If 表示行 <= 2 Then にしてみます。
>
>If 最終行 >= 最終行 Then を
>
>If 表示行 >= 最終行 Then  にしてみます。

上記のようにコードを変えてみましたが、表示できませんでした。

【54711】Re:転記したワークシートのデーターをユ...
質問  VBWASURETA  - 08/3/27(木) 12:26 -

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

こんにちは。

>>If 最終行 <= 2 Then を
>>
>>If 表示行 <= 2 Then にしてみます。
>>
>>If 最終行 >= 最終行 Then を
>>
>>If 表示行 >= 最終行 Then  にしてみます。
>
>上記のようにコードを変えてみましたが、表示できませんでした。

ここは移動だけの問題ですよ?
で、表示部分を明確に提示してもらえないですか?
内容はわかっているいるので、例ではなく
[database]というのはどいう書き方をしているかが問題ですよ。

【54733】Re:転記したワークシートのデーターをユ...
発言  Regina  - 08/3/27(木) 22:57 -

引用なし
パスワード
   ▼VBWASURETA さん:
いつもありがとうございます。
>[database]というのはどいう書き方をしているかが問題ですよ。

これについては、ツールバーの「挿入」→「名前」→「定義」で範囲を
「=データーベース!$A$4:$L$9」の部分を[database]としています。

【54735】Re:転記したワークシートのデーターをユ...
質問  VBWASURETA  - 08/3/28(金) 2:13 -

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

範囲を定義してるわけですか。
因みにCellsで指定した場合ですが、
Sheets("Database").Cells(2行以降から, 1)と変わりませんよ?

で、A4から範囲しているようですが、データがちゃんと入ってますか?

【54736】Re:転記したワークシートのデーターをユ...
発言  Regina  - 08/3/28(金) 7:14 -

引用なし
パスワード
   ▼VBWASURETA さん:
お忙しいのに、ありがとうございます。

>範囲を定義してるわけですか。
>因みにCellsで指定した場合ですが、
>Sheets("Database").Cells(2行以降から, 1)と変わりませんよ?
すみません、上記のコードの意味は、
TextBox1 = [Database].Cells(表示行, 1)と変わらないということでしょうか?


>で、A4から範囲しているようですが、データがちゃんと入ってますか?

A4には「患者ID」、B4には「氏名」というように、A4からL4までは、名前がデーターとして入っています。A5からL5の行が、データー転記のレコードの始めの行となります。

【54737】Re:転記したワークシートのデーターをユ...
回答  VBWASURETA  - 08/3/28(金) 9:09 -

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

おはようございます。


>>Sheets("Database").Cells(2行以降から, 1)と変わりませんよ?
>すみません、上記のコードの意味は、
>TextBox1 = [Database].Cells(表示行, 1)と変わらないということでしょうか?

そいうことですが、
データはA4からですよね?
でも上記の指定だとA2から開始されますよ?という意味です。
A2からデータがないのでしたらA4から開始するようにしないとだめです。

【54774】Re:転記したワークシートのデーターをユ...
発言  Regina  - 08/3/29(土) 11:04 -

引用なし
パスワード
   ▼VBWASURETA さん:
ご指摘ありがとうございます。今、どんどん混乱してきて分からなくなっています。

そいうことですが、
データはA4からですよね?
でも上記の指定だとA2から開始されますよ?という意味です。
A2からデータがないのでしたらA4から開始するようにしないとだめです。

データーはA4から始まっています。A4のセルには「患者ID」と入力していて、A5のセルには「12345」というように実際の患者さんのIDを入力しています。


ワークシートの既存のデーターが入力されている部分を"Database"として名づけていますが、そもそもこの方法自体が間違っているのかなと思い始めました。

データーはこれからも、新規登録されて追加していくので、データー範囲の5件分以上にレコードは増えていきます。

ワークシートのデーターをユーザーフォームに表示していくには、他に方法はありますか?

【54776】Re:転記したワークシートのデーターをユ...
回答  ツル  - 08/3/29(土) 13:01 -

引用なし
パスワード
   登録用ユーザーフォームに表示するようにしたらいかがでしょう?
シートに転記できたのですから、その逆をいけばいいのではないでしょうか?

【54785】Re:転記したワークシートのデーターをユ...
発言  Regina  - 08/3/30(日) 0:26 -

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

ありがとうございます。

>登録用ユーザーフォームに表示するようにしたらいかがでしょう?
>シートに転記できたのですから、その逆をいけばいいのではないでしょうか?

登録用のユーザーフォームにワークシートのデーターを表示するために逆のことをする場合、VBAのコードはどんな関数を使えば宜しいですか?

【54786】Re:転記したワークシートのデーターをユ...
回答  Hirofumi  - 08/3/30(日) 0:56 -

引用なし
パスワード
   私だったらこんな形にします
データー閲覧用、入力用区別は有りません同じ物です
ただ、全文は、サイトの上限文字数を超えてしまうので
「入院・外来」所までとしています
UserFormのコントロールは、ReginaさんのUserForm4の構成に
以下のコントロールを追加して下さい
CommandButton1:入力ボタン
CommandButton2:行削除ボタン
ScrollBar1:レコード移動用
尚、レコード移動は、<前 →CommandButton9、次> →CommandButton10の他に
ScrollBar1で行うのと、TextBox1に「患者ID」を入力してフォーカスを移動すると
患者IDが有れば、そのレコードに移動しますし、無ければ新規レコード位置に移動します

'UserFormのコード
Option Explicit

'探索Keyの有る列位置(基準位置からの列Offset)
Private Const clngKeys As Long = 0
'入力モードと表示モードの切り替え
Public blnInput As Boolean
'Listの先頭、最左の列見出しのセル位置
Private rngList As Range
'Listの行数(最終行)
Private lngRows As Long
'操作対象行位置(表示行)
Private lngCurrent As Long
'IDの最大値
Private lngMaxNum As Long

Private Sub UserForm_Initialize()
  
  TextBox1.TabStop = False
  
  'Listの先頭セル位置を基準として設定(最左の列見出しのセル位置:[患者ID])
  Set rngList = Worksheets("Sheet1").Cells(4, "A")
  With rngList
    .Parent.Activate
    'Listのデータ行数取得
    lngRows = .Offset(Rows.Count - .Row, clngKeys).End(xlUp).Row - .Row
    If lngRows <= 0 Then
      lngRows = 0
      lngMaxNum = 0
    Else
      lngMaxNum = Application.WorksheetFunction _
            .Max(.Offset(1).Resize(lngRows))
    End If
  End With
    
  'スクロールバーの初期化
  With ScrollBar1
    .Max = lngRows + 1
    .Min = 1
    .TabStop = False
    .LargeChange = 5
  End With
  
End Sub

Private Sub UserForm_Activate()
  
  '入力フォーム指定なら
  If blnInput Then
    '入力ボタン、削除ボタンを使用可に
    CommandButton1.Enabled = True
    CommandButton2.Enabled = True
    'データ範囲にデータが有るなら
    If lngRows > 0 Then
      '操作行を最終行+1に
      lngCurrent = lngRows + 1
      'スクロールバーを操作行に設定
      ScrollBar1.Value = lngCurrent
    Else
      '操作行を先頭行に
      lngCurrent = 1
      GetData lngCurrent
    End If
  Else
    '入力ボタン、削除ボタンを使用不可に
    CommandButton1.Enabled = False
    CommandButton2.Enabled = False
    '操作行を先頭行に
    lngCurrent = 1
    GetData lngCurrent
  End If
  
End Sub

Private Sub UserForm_Terminate()

  Set rngList = Nothing
  
End Sub

Private Sub OptionButton1_Click()
  With OptionButton1
    .Parent.Tag = .Caption
  End With
End Sub

Private Sub OptionButton2_Click()
  With OptionButton2
    .Parent.Tag = .Caption
  End With
End Sub

Private Sub OptionButton3_Click()
  With OptionButton3
    .Parent.Tag = .Caption
  End With
End Sub

Private Sub OptionButton4_Click()
  With OptionButton4
    .Parent.Tag = .Caption
  End With
End Sub

Private Sub CommandButton1_Click()
  
'  データを転記

  Dim i As Long

  '書き換えが、データ範囲内なら
  If lngCurrent > lngRows Then
    'List行数をインクリメント
    lngRows = lngRows + 1
    'スクロールバーの範囲を更新
    ScrollBar1.Max = lngRows + 1
  End If
  'シートにデータの転記
  SetData lngCurrent
  
  '新規入力位置を表示
  lngCurrent = lngRows + 1
  GetData lngCurrent
  
End Sub

Private Sub CommandButton2_Click()

' 該当行を削除

  Dim i As Long
  
  If lngCurrent <= lngRows Then
    Beep
    If MsgBox("Key " & TextBox1.Text & " のDataを削除します", _
        vbExclamation + vbOKCancel, "削除") = vbOK Then
      '操作行を削除
      rngList.Offset(lngCurrent).EntireRow.Delete
      'List行数をディクリメント
      lngRows = lngRows - 1
      'スクロールバーの範囲を更新
      ScrollBar1.Max = lngRows + 1
      'データ行が有るなら
      If lngRows > 0 Then
        '次のデータを表示
        RowUpDown
      Else
        '操作行を最終行に
        lngCurrent = lngRows + 1
        'コントロールに値読み込み
        GetData lngCurrent
      End If
    End If
  End If
    
End Sub

Private Sub CommandButton9_Click()
'  行のDouwn
  lngCurrent = lngCurrent - 1
  RowUpDown
End Sub

Private Sub CommandButton10_Click()
'  行のUp
  lngCurrent = lngCurrent + 1
  RowUpDown
End Sub

Private Sub CommandButton11_Click()
  Unload Me
End Sub

Private Sub ScrollBar1_Change()
  lngCurrent = ScrollBar1.Value
  RowUpDown
End Sub

Private Sub TextBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean)

  '存在Flag(0以外は、該当Keyが存在する)
  Dim lngFound As Long
  Dim lngOver As Long
  Dim vntKey As Variant
  
  With TextBox1
    If .Text <> "" Then
      '探索Keyを取得
      vntKey = .Text
      'Listにデータ行が有るなら
      If lngRows > 0 Then
        'Listから該当するKeyの行を探索(探索Keyが数値の場合)
        lngFound = RowSearch(Val(vntKey), rngList.Offset(1, _
                  clngKeys).Resize(lngRows), lngOver)
        'Listから該当するKeyの行を探索(探索Keyが文字列の場合)
'        lngFound = RowSearch(vntKey, rngList.Offset(1, _
                  clngKeys).Resize(lngRows), lngOver)
      Else
        lngFound = 0
        lngOver = 1
      End If
      '探索Keyの該当行が有る場合
      If lngFound > 0 Then
        '操作行を存在行に
        lngCurrent = lngFound
        'コントロールに値読み込み
        GetData lngCurrent
      Else
        '操作行を行挿入位置に設定
        lngCurrent = lngOver
        'コントロールに値読み込み
        GetData lngCurrent
        TextBox1.Text = vntKey
      End If
    Else
      '操作行を最終行+1位置に設定
      lngCurrent = lngRows + 1
      'コントロールに値読み込み
      GetData lngCurrent
      TextBox1.Text = lngMaxNum + 1
    End If
  End With

End Sub

Private Sub GetData(lngRow As Long)

'  1行分のListデータを各コントロールに代入

  With rngList.Offset(lngRow)
    .Activate
    If lngRow <= lngRows Then
      TextBox1.Text = .Offset(, 0).Value
    Else
      TextBox1.Text = lngMaxNum + 1
    End If
    TextBox2.Text = .Offset(, 1).Value
    Frame8.Tag = .Offset(, 2).Value
    SetOptionValue Frame8
    TextBox3.Text = .Offset(, 3).Value
    TextBox4.Text = .Offset(, 4).Value
    Frame2.Tag = .Offset(, 5).Value
    SetOptionValue Frame2
  End With
  
  'スクロールバーの表示位置更新
  With ScrollBar1
    If .Value <> lngRow Then
      .Value = lngRow
    End If
  End With
  
  TextBox2.SetFocus
  
End Sub

Private Sub SetData(lngRow As Long)

'  各コントロールデータを1行分のListに代入

  With rngList.Offset(lngRow)
    .Offset(, 0).Value = TextBox1.Text
    .Offset(, 1).Value = TextBox2.Text
    .Offset(, 2).Value = Frame8.Tag
    .Offset(, 3).Value = TextBox3.Text
    .Offset(, 4).Value = TextBox4.Text
    .Offset(, 5).Value = Frame2.Tag
  End With
  
  'IDが最大値を超す場合、最大値を書き換え
  If lngMaxNum < Val(TextBox1.Text) Then
    lngMaxNum = Val(TextBox1.Text)
  End If
  
  'スクロールバーの表示位置更新
  With ScrollBar1
    If .Value <> lngRow Then
      .Value = lngRow
    End If
  End With
  
End Sub

Private Function RowSearch(vntKey As Variant, _
            rngScope As Range, _
            Optional lngOver As Long) As Long

  Dim vntFind As Variant
  
  If rngScope Is Nothing Then
    lngOver = 1
    Exit Function
  End If
  lngOver = rngScope.Rows.Count + 1
  'Matchによる探索
  vntFind = Application.Match(vntKey, rngScope, 0)
  'もし、エラーで無いなら
  If Not IsError(vntFind) Then
    '戻り値として、行位置を代入
    RowSearch = vntFind
  End If
  
End Function

Private Sub RowUpDown()

'  行のUP、Douwn

  'LIst範囲にデータが無い場合
  If lngRows < 1 Then
    lngCurrent = 0
    Exit Sub
  End If

  '操作行が、LIst範囲を超えるなら
  If lngCurrent > lngRows Then
    '操作行を最終行+1に
    lngCurrent = lngRows + 1
  ElseIf lngCurrent < 1 Then
    '操作行を先頭行に
    lngCurrent = 1
  End If
  
  'コントロールに値読み込み
  GetData lngCurrent
  
End Sub

Private Sub SetOptionValue(fraObject As MSForms.Frame)
  
' 文字列とOptionButtonのCaptionが同じ場合、OptionButtonをTrueにする

  Dim i As Long
  Dim vntValue As Variant
  
  'Frameに就いて
  With fraObject
    '与えられた文字列に区切り文字を追加
    vntValue = .Tag
    'Frame内のControlに就いて繰り返し
    For i = 0 To .Controls.Count - 1
      'ControlがOptionButtonであるなら
      If TypeName(.Controls(i)) = "OptionButton" Then
        '同じ場合
        If vntValue = .Controls(i).Caption Then
          'OptionButtonをTrueに
          .Controls(i).Value = True
          Exit For
        End If
      End If
    Next i
    '該当がない場合
    If i > .Controls.Count - 1 Then
      For i = 0 To .Controls.Count - 1
        '先頭のOptionButtonを
        If TypeName(.Controls(i)) = "OptionButton" Then
          'Trueに
          .Controls(i).Value = True
          Exit For
        End If
      Next i
    End If
  End With
  
End Sub

UserFormを呼び出すコード(標準モジュール)

Public Sub ViewOnly()
  With UserForm1
    .blnInput = False
    .Show
  End With  
End Sub

Public Sub InputForm()
  With UserForm1
    .blnInput = True
    .Show
  End With
End Sub

【54794】Re:転記したワークシートのデーターをユ...
発言  Regina  - 08/3/30(日) 13:24 -

引用なし
パスワード
   ▼Hirofumi さん:
ありがとうございます。膨大なコード解説非常に助かりました。
只今、コードを自分なりに読み込んでいます。

 Set rngList = Worksheets("Sheet1").Cells(4, "A")

 上記のコードの"Sheet1"は、今データー範囲の"Database"なのか、ワークシート名の"データーベース"なんでしょうか?

'Listの先頭セル位置を基準として設定(最左の列見出しのセル位置:[患者ID])

なので、"データーベース"でいいのかなと思っています。

未だ、上手く解釈できていなくてすみません。

【54795】Re:転記したワークシートのデーターをユ...
回答  Hirofumi  - 08/3/30(日) 13:37 -

引用なし
パスワード
   ▼Regina さん:
>▼Hirofumi さん:
>ありがとうございます。膨大なコード解説非常に助かりました。
>只今、コードを自分なりに読み込んでいます。
>
> Set rngList = Worksheets("Sheet1").Cells(4, "A")
>
> 上記のコードの"Sheet1"は、今データー範囲の"Database"なのか、ワークシート名の"データーベース"なんでしょうか?
>
>'Listの先頭セル位置を基準として設定(最左の列見出しのセル位置:[患者ID])
>
>なので、"データーベース"でいいのかなと思っています。
>
>未だ、上手く解釈できていなくてすみません。

このコードでは、データの範囲名(Database)を使っていません
因って、"Sheet1"は、データの有るシート名です
シート名が「データーベース」なら

 Set rngList = Worksheets("データーベース").Cells(4, "A")

として下さい

【54803】Re:転記したワークシートのデーターをユ...
発言  Regina  - 08/3/30(日) 22:27 -

引用なし
パスワード
   ▼Hirofumi さん:
何度もすみません。教えていただいたコードを入れてみました。
---------------------------------------------------------
Private Sub GetData(lngRow As Long)

'  1行分のListデータを各コントロールに代入

  With rngList.Offset(lngRow)
    .Activate
    If lngRow <= lngRows Then
      TextBox1.Text = .Offset(, 0).Value
    Else
      TextBox1.Text = lngMaxNum + 1
    End If
    TextBox2.Text = .Offset(, 1).Value
    Frame8.Tag = .Offset(, 2).Value
    SetOptionValue Frame8
    TextBox3.Text = .Offset(, 3).Value
    TextBox4.Text = .Offset(, 4).Value
    Frame2.Tag = .Offset(, 5).Value
    SetOptionValue Frame2
   
  End With
 
  'スクロールバーの表示位置更新
  With ScrollBar1
    If .Value <> lngRow Then
      .Value = lngRow
    End If
  End With
 
  TextBox2.SetFocus
 
End Sub
------------------------------------------------

上記の With rngList.Offset(lngRow)  について、実行時エラーが出てしまいました。「オブジェクト変数またはWithブロック変数が設定されていません」と表示されました。

どこかで、Dimを使ってオブジェクトの宣言をする必要がありますか?

【54817】Re:転記したワークシートのデーターをユ...
発言  VBWASURETA  - 08/3/31(月) 15:08 -

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

すみません見てない間に結構複雑な展開になってますね・・・

>上記の With rngList.Offset(lngRow)  について、実行時エラーが出てしまいました。「オブジェクト変数またはWithブロック変数が設定されていません」と表示されました。
>
>どこかで、Dimを使ってオブジェクトの宣言をする必要がありますか?

まず、どんなプログラムでもそうですが、変数であれば定義しないといけません。


>このコードでは、データの範囲名(Database)を使っていません
>因って、"Sheet1"は、データの有るシート名です
>シート名が「データーベース」なら
> Set rngList = Worksheets("データーベース").Cells(4, "A")
>として下さい

後、Hirofumiさんが上記の内容を書かれてますが反映してますか?

【54823】Re:転記したワークシートのデーターをユ...
回答  Hirofumi  - 08/3/31(月) 18:13 -

引用なし
パスワード
   >何度もすみません。教えていただいたコードを入れてみました。
>---------------------------------------------------------
>Private Sub GetData(lngRow As Long)
>
>'  1行分のListデータを各コントロールに代入
>
>  With rngList.Offset(lngRow)
>    .Activate
>    If lngRow <= lngRows Then
>      TextBox1.Text = .Offset(, 0).Value
>    Else
>      TextBox1.Text = lngMaxNum + 1
>    End If
>    TextBox2.Text = .Offset(, 1).Value
>    Frame8.Tag = .Offset(, 2).Value
>    SetOptionValue Frame8
>    TextBox3.Text = .Offset(, 3).Value
>    TextBox4.Text = .Offset(, 4).Value
>    Frame2.Tag = .Offset(, 5).Value
>    SetOptionValue Frame2
>   
>  End With
> 
>  'スクロールバーの表示位置更新
>  With ScrollBar1
>    If .Value <> lngRow Then
>      .Value = lngRow
>    End If
>  End With
> 
>  TextBox2.SetFocus
> 
>End Sub
>------------------------------------------------
>
>上記の With rngList.Offset(lngRow)  について、実行時エラーが出てしまいました。「オブジェクト変数またはWithブロック変数が設定されていません」と表示されました。
>
>どこかで、Dimを使ってオブジェクトの宣言をする必要がありますか?

UserFormのコードを記述するモジュールの先頭、「Option Explicit」の下に
以下の、宣言が記述されていますか?

Option Explicit

'探索Keyの有る列位置(基準位置からの列Offset)
Private Const clngKeys As Long = 0
'入力モードと表示モードの切り替え
Public blnInput As Boolean
'Listの先頭、最左の列見出しのセル位置
Private rngList As Range
'Listの行数(最終行)
Private lngRows As Long
'操作対象行位置(表示行)
Private lngCurrent As Long
'IDの最大値
Private lngMaxNum As Long

これが、モジュールレベル(今回はUserFormのモジュール全体で、使用可能な変数の宣言)の
変数宣言です

Reginaさんの最初の質問の以下の宣言と同じ事です(Option Explicitの上に書いてあるけど?)

>Dim 表示行 As Long
>Dim 最終行 As Long
>Option Explicit

【54825】Re:転記したワークシートのデーターをユ...
回答  Hirofumi  - 08/3/31(月) 20:33 -

引用なし
パスワード
   あ!!、最初の質問をよく見たら

>Private Sub UserForm4_Initialize()
> 表示行 = 2  →先頭レコードが2行目からなので、表示行には2を代入
> 最終行 = WorksheetFunction.CountA([Database].Resize(, 1))
>        →COUNT関数を使って、左端列の行数を数えて代入
> Call データー表示
>End Sub

と成っていますね?
此れをやると、UserFormの初期化イベントでは無く、ただのSubプロシージャに成ってしまいます

「Private Sub UserForm4_Initialize()」は、UserFormの初期化イベントなので、
UserForm1でも、UserForm3でも、UserForm4でも、必ず

「Private Sub UserForm_Initialize()」として下さい

多分、私のコードも「Private Sub UserForm_Initialize()」のUserFormの後ろに番号を
付け足しているのでは?

また、上記の理由で、最初の質問のコードも上手く動かなかったと思われます

【54826】Re:転記したワークシートのデーターをユ...
回答  Hirofumi  - 08/3/31(月) 21:30 -

引用なし
パスワード
   尚、以下のイベントプロシージャも同じで、UserFormの後ろに番号は入れないでください

Private Sub UserForm_Activate()
Private Sub UserForm_Terminate()

【54827】Re:転記したワークシートのデーターをユ...
発言  Regina  - 08/3/31(月) 22:30 -

引用なし
パスワード
   ▼Hirofumi さん:
的確なご指摘ありがとうございました。UserFormのあとに番号を入力していました。表示が出来るようになりました。すごく嬉しいです。
------------------------------------------------------------------------
Private Sub UserForm_Activate()
 
  '入力フォーム指定なら
  If blnInput Then
    '入力ボタン、削除ボタンを使用可に
    CommandButton1.Enabled = True
    CommandButton2.Enabled = True
    'データ範囲にデータが有るなら
    If lngRows > 0 Then
      '操作行を最終行+1に
      lngCurrent = lngRows + 1
      'スクロールバーを操作行に設定
      ScrollBar1.Value = lngCurrent
    Else
      '操作行を先頭行に
      lngCurrent = 1
      GetData lngCurrent
    End If
  Else
    '入力ボタン、削除ボタンを使用不可に
    CommandButton1.Enabled = False
    CommandButton2.Enabled = False
    '操作行を先頭行に
    lngCurrent = 1
    GetData lngCurrent
  End If
 
End Sub
-----------------------------------------------------------
上記コードも番号を外しました。CommandButton1と2は入力ボタンと行削除ボタンですが、ボタンの部分の表示が使えないようになって表示されています。これも私のどこかの設定ミスでしょうか?

まったくデーターの無いレコードの部分にスクロールバーを移動しても、>次のボタンを押しても、新しいレコードを登録フォームからデーター入力しても、患者IDのTextBoxに常に21197と表示されます。

これは、CommandButton1と2のボタンが表示されないことに関係ありますか?
重ね重ねの質問で大変恐縮ですが、お時間の宜しい時にご回答下さい。

また、教えていただいた、コードを学ぶためにはどのような書籍を使えば宜しいですか?今は、初心者用のエクセルのVBAの本を数冊持っています。

【54830】Re:転記したワークシートのデーターをユ...
発言  VBWASURETA  - 08/4/1(火) 9:55 -

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

また横から失礼します。

>上記コードも番号を外しました。CommandButton1と2は入力ボタンと行削除ボタンですが、ボタンの部分の表示が使えないようになって表示されています。これも私のどこかの設定ミスでしょうか?

ですが、

ちゃんとコメントに書いてますよ?

>Private Sub UserForm_Activate()
     ・
     ・
     ・
>    '入力ボタン、削除ボタンを使用不可に
>    CommandButton1.Enabled = False
>    CommandButton2.Enabled = False
>    '操作行を先頭行に
>    lngCurrent = 1
>    GetData lngCurrent

で、この処理が動くタイミング理解されてますか?
因みにActivateイベントはフォームが前面(アクティブ)に
なったときに実行されます。

なので、ボタンが押せなくなるのは上記の部分が実行されているからでは?

後、個人的にはVBAについて勉強するなら書籍より、Web上で調べる方が
わかり易いです。

この質問箱のトップからリンクに移動すると色々なサイトのリンクがあります。

【54843】Re:転記したワークシートのデーターをユ...
発言  Regina  - 08/4/1(火) 16:08 -

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

何回でも、横レスお願いします。ありがたいです。
>で、この処理が動くタイミング理解されてますか?
>因みにActivateイベントはフォームが前面(アクティブ)に
>なったときに実行されます。

この処理の動くタイミングは良く分かりません。また、分からないから常に、「21197」という値がなぜ、TextBoxに代入されているのかも分かりません。

お手数ですが教えていただけるとうれしいです。

【54844】Re:転記したワークシートのデーターをユ...
発言  VBWASURETA  - 08/4/1(火) 16:51 -

引用なし
パスワード
   さくっとしか Hirofumiさんのソースを見てませんが、

動くタイミングはフォームの初期表示の時です。
後、その「21197」コードはどの項目かや、データ自体わからないので、
回答できませんがデータにその数値があるのでは?

次に以下のこれを呼ぶような処理入れてます?
このモジュールを呼ばない限りボタンは切り替わらないですね。

UserFormを呼び出すコード(標準モジュール)

>Public Sub ViewOnly()
>  With UserForm1
>    .blnInput = False
>    .Show
>  End With  
>End Sub

>Public Sub InputForm()
>  With UserForm1
>    .blnInput = True
>    .Show
>  End With
>End Sub

【54847】Re:転記したワークシートのデーターをユ...
発言  わさび  - 08/4/1(火) 18:29 -

引用なし
パスワード
   ▼VBWASURETA さん、Regina さん

これまでのコードや細かい仕様を読んでいない人間が発言して申し訳ありません。

が、ここがちょっと気になりました。
>後、その「21197」コードはどの項目かや、データ自体わからないので、
>回答できませんがデータにその数値があるのでは?

「21197」の表示形式を「日付」にすると、「1958/1/12」になるなぁ…と。
ひょっとしてこれは何か関係あるのかなと思い、書き込ませていただきました。

まったく検討違いでしたら、大変申し訳ございません。

【54848】Re:転記したワークシートのデーターをユ...
回答  Hirofumi  - 08/4/1(火) 19:15 -

引用なし
パスワード
   VBWASURETAさんフォローありがとうございます

>上記コードも番号を外しました。
>CommandButton1と2は入力ボタンと行削除ボタンですが、
>ボタンの部分の表示が使えないようになって表示されています。
>これも私のどこかの設定ミスでしょうか?
>
>まったくデーターの無いレコードの部分にスクロールバーを移動しても、
>>次のボタンを押しても、新しいレコードを登録フォームからデーター入力しても、
>患者IDのTextBoxに常に21197と表示されます。
>
>これは、CommandButton1と2のボタンが表示されないことに関係ありますか?
>重ね重ねの質問で大変恐縮ですが、お時間の宜しい時にご回答下さい。
>
>また、教えていただいた、コードを学ぶためにはどのような書籍を使えば宜しいですか?
>今は、初心者用のエクセルのVBAの本を数冊持っています。

先ず、このUserFormはカッコ良く言えば、
入力・修正モードと閲覧モードの切り替えが利くように 成っています
この切り替えは、UserFormの呼出コード中で行います
Upしたコードの一番下に、以下の様なコードが書いて有った筈です

UserFormを呼び出すコード(標準モジュール)

Public Sub ViewOnly()
  With UserForm1
    .blnInput = False
    .Show
  End With  
End Sub

Public Sub InputForm()
  With UserForm1
    .blnInput = True
    .Show
  End With
End Sub

これを説明すると、

1、「Sub InputForm」を実行
 UserFormは、「入力・修正モード」で立ち上がります
 この場合、UserForm表示する行は新規入力行です(Listの最終行の下)
 そして、TextBox1に表示される番号は、Listの「患者ID」の最大値+1です
 これは、簡易的な自動連番機能を持たせて在る為にこう成ります
 ここで、振り出された番号で入力したい場合、TextBox1に番号を入力します
 入力後、フォーカスをTextBox2に移すと、TextBox1の番号がListにない場合
 そのまま、新規入力と成ります
 また、TextBox1の番号がListに有る場合、
 UserFormの表示は、その番号が有る行に移動してその行の修正モードと成ります
 この様に入力・修正を行った後、入力ボタンを押すと、新規入力なら最下行に
 レコードが追加され、次の新規入力行に表示が移動します
 また、修正モードの場合、表示されている行が変更され、表示は新規入力行に移動します
 詰まり、このモードでは、UserFormに表示されているレコードが変更対象となります
 また、修正は、CommandButton9、10で移動するか、スクロールバーで移動した
 UserFormの表示行でも行えます
 
2、「Sub ViewOnly」を実行
 UserFormは、「閲覧モード」で立ち上がります
 この場合、UserFormは、先頭行を表示し、「入力」「行削除」ボタンは使用不可と成ります
 詰まり、閲覧専用と成ります

この違いは、見ての通り、各プロシージャの「With UserForm1」
(UserForm1は、Reginaさんが作ったUserFormの名前に合わせて下さい)
の下「.blnInput = True」「.blnInput = False」で
「.blnInput = True」を指定すれば「入力・修正モード」
「.blnInput = False」を指定すれば、「閲覧モード」で立ち上がります
(明示的に書きましたがこれを指定せず立ち上げた場合、「.blnInput = False」を指定したと同じになります)

尚、シートにボタンを設けてUserFormを立ち上げる場合、
ボタンのコードを上記の標準モジュールのコードを参考にして下さい

【54849】Re:転記したワークシートのデーターをユ...
回答  Hirofumi  - 08/4/1(火) 19:34 -

引用なし
パスワード
   尚、書き忘れましたが、

 Set rngList = Worksheets("データーベース").Cells(4, "A")

の「.Cells(4, "A")」とは、「患者ID」と言う列見出しの有る位置で、
データの先頭位置(「12345」)では無いのでくれぐれも間違いの無いようにして下さい
また、「患者ID」は、数値データであると想定していますので、
これが文字列データの場合、上手く動かないので言って下さい

また、OptionButtonのセルへの書き込みは、
各OptionButtonのCaption(コントロールの表題)が書き込まれるので注意して下さい

【54850】Re:転記したワークシートのデーターをユ...
発言  Regina  - 08/4/1(火) 23:12 -

引用なし
パスワード
   ▼Hirofumi さん:
毎回丁寧なご回答ありがとうございます。

>尚、シートにボタンを設けてUserFormを立ち上げる場合、
>ボタンのコードを上記の標準モジュールのコードを参考にして下さい

今の所、ワークシート上に登録(新規の入力)とデーター閲覧のボタンを設けてあります。今まで、ユーザーフォームはボタンからしか立ち上げたことが無いのですが、シートにボタンをつけない場合は、そのままボタンとボタンに貼り付けてあるマクロを削除すればよいのでしょうか?
-------------------------------------------------------------------------
Public Sub ViewOnly()
  With UserForm1
    .blnInput = False
    .Show
  End With  
End Sub

Public Sub InputForm()
  With UserForm1
    .blnInput = True
    .Show
  End With
End Sub
---------------------------------------------
上記のコードは、UserForm4のコード中にそのまま、upしていただいたコードと共にそのまま貼り付けています。上記のコードの貼り付ける場所は、UserForm4のコード内のままで宜しいですか?

お忙しいのに、みなさん、回答してくださって、ありがとうございます。自分でも持っている本やネットで調べていますが、基本的な部分がまだまだですみません。

【54873】Re:転記したワークシートのデーターをユ...
回答  Hirofumi  - 08/4/2(水) 19:17 -

引用なし
パスワード
   >上記のコードは、UserForm4のコード中にそのまま、
>upしていただいたコードと共にそのまま貼り付けています。
>上記のコードの貼り付ける場所は、UserForm4のコード内のままで宜しいですか?

違います
このコードは標準モジュールに記述して下さい
UserForm4に書いて有るUpされたコードは削除して下さい

1、シートのボタンで操作する場合
 (この場合、標準モジュールに、Upされたコードを記述しなくても構いません)
 シートに張り付けられるボタンが何んで有るかに因って替わりますが、
 コントロールツールボックスから張りつけたボタンなら、(CommandButton1と2とします)
 ボタンの有る、シートのコードモジュールに以下の様に記述します
 (若しくは、現状のボタンのコードを以下の様に直して下さい)

Option Explicit

Private Sub CommandButton1_Click()

'  入力フォーム表示

  With UserForm4
    .blnInput = True
    .Show
  End With
    
End Sub

Private Sub CommandButton2_Click()

' 閲覧フォーム表示

  With UserForm4
    .blnInput = False
    .Show
  End With
  
End Sub

2、「シートにボタンをつけない場合は」で運用する場合は、
 Upされたコードを標準モジュール(「挿入」→「を標準モジュール」で追加されます)
 に其のまま記述して下さい
 ただしUserForm1の所は、ReginaさんのUserFormのオブジェクト名に直して下さい
 実行は、シートの画面で(VBEの画面では有りませんの気を付けて下さい)
 「ツール」→「マクロ」→「マクロ」でマクロのダイアログが出ますので
 そこから、「ViewOnly」を選べば、閲覧フォームが開きますし、
 「InputForm」を選べば、入力フォームが開きます

【54877】Re:転記したワークシートのデーターをユ...
お礼  Regina  - 08/4/3(木) 0:14 -

引用なし
パスワード
   いろいろご指導いただいたおかげで、データー閲覧から登録・行削除まで完成する事が出来ました。

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

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