Excel VBA質問箱 IV

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

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


82 / 3841 ページ ←次へ | 前へ→

【80834】ゲーム制作:自機の操作と敵機の自動移動...
質問  SHUN  - 19/5/21(火) 13:26 -

引用なし
パスワード
   VBAで自機を動かすプログラム、敵機を自動で移動するプログラムはそれぞれ組めましたが、
その2つを同時に動かす段階で躓いています。

Call '自機を動かすプログラム=aとします。
Call ’敵機を動かすプログラム=bとします。
とすると、aのプログラム終了後にbのプログラム処理となり、
1つのプロシージャ内に両方入れようとすると上手くいきません。

参考に、それぞれのソースを以下に貼り付けます。

Sub 自機発生()

Dim i As Integer
Dim j As Integer

Dim i2 As Integer
Dim j2 As Integer


Cells.Interior.ColorIndex = xlNone


  i = 10
  j = 10
  
    Cells(i, j).Interior.ColorIndex = 6
    
    
 Do
 
    '自機発生、操作
    
    If GetAsyncKeyState(37) <> 0 Then
    
    Cells(i, j).Interior.ColorIndex = xlNone
      If j <= 3 Then
      j = 17
      Else
      j = j - 1
      End If
    Cells(i, j).Interior.ColorIndex = 6
    
    End If
    
    If GetAsyncKeyState(38) <> 0 Then
    
    Cells(i, j).Interior.ColorIndex = xlNone
      If i <= 3 Then
      i = 17
      Else
      i = i - 1
      End If
    Cells(i, j).Interior.ColorIndex = 6
    
    End If
    
    If GetAsyncKeyState(39) <> 0 Then
    
    Cells(i, j).Interior.ColorIndex = xlNone
      If j >= 17 Then
      j = 3
      Else
      j = j + 1
      End If
    Cells(i, j).Interior.ColorIndex = 6
    
    End If
    
    If GetAsyncKeyState(40) <> 0 Then
    
    Cells(i, j).Interior.ColorIndex = xlNone
      If i >= 17 Then
      i = 3
      Else
      i = i + 1
      End If
    Cells(i, j).Interior.ColorIndex = 6
   
    End If
    
    If GetAsyncKeyState(13) <> 0 Then
    
    Exit Do
    
    End If
    
  DoEvents

  Sleep 90
  
  Loop


End Sub

Sub 発生()
  Dim i As Integer
  Dim j As Integer

  Randomize
  

  i = 3
  j = 15
  
  Do
  
  '敵機発生、ランダムで移動
  
    Cells(i, j).Interior.ColorIndex = xlNone

    
  If 0 <= Rnd And Rnd < 0.25 Then
    If i >= 17 Then
    i = 3
    Else
    i = i + 1
    End If
  Else
  If 0.25 <= Rnd And Rnd < 0.5 Then
    If j >= 17 Then
    j = 3
    Else
    j = j + 1
    End If
  Else
  If 0.5 <= Rnd And Rnd < 0.75 Then
    If i <= 3 Then
    i = 17
    Else
    i = i
    End If
  Else
  If 0.75 <= Rnd And Rnd < 1 Then
    If j <= 3 Then
    j = 17
    Else
    j = j - 1
    End If
 
  Cells(i, j).Interior.ColorIndex = 3
  
  End If
  
     If GetAsyncKeyState(13) <> 0 Then
    
     Exit Do
    
     End If
  
  DoEvents
  
  
  Sleep 90

 Loop


End Sub

よろしくお願いいたします。
・ツリー全体表示

【80833】Re:f2+enterをマクロを使って押させたい
お礼  Mp  - 19/5/20(月) 13:06 -

引用なし
パスワード
   返信遅くなり申し訳ございません

無事にリンクを挿入できました。
ありがとうございました。

▼マナ さん:
>▼Mp さん:
>
>>ブックAのセルにあるフォルダのパスを読み込んで、ブックBに貼り付けました。
>>そのあとそのパスをf2+enterで水色?に表示させてクリックしたらそのフォルダを開けるようにしたいです。
>
>こことかを参考になりませんか
>ht tps://excelwork.info/excel/hyperlinks/
>
>
・ツリー全体表示

【80832】Re:[無題]
お礼  しいな  - 19/5/19(日) 22:53 -

引用なし
パスワード
   ▼マナ さん:
マナさんご丁寧にありがとうございました。今VBAの本と照らし合わせながら、こうやって作っていくんだと勉強させていただいています。
本当に奥が深くて勉強になります。ありがとうございました。


>▼しいな さん:
>
>ごめんなさい。毎回ピボットを作り直す必要なかったです。
>最初に、手作業で作っておけば、
>
>ws.Cells(9).PivotTable.SourceData = r.Address(, , xlR1C1, True)
>
>これだけで十分でした。
・ツリー全体表示

【80831】Re:十字キーで色をつけたセルの移動の方法
お礼  SHUN  - 19/5/18(土) 12:38 -

引用なし
パスワード
   ありがとうございます。
初心者なのでユーザーフォームとは?となってしまいましたが、
別解も理解したほうが後々幅が広がると思うので、勉強しようと思います。
ありがとうございました。
・ツリー全体表示

【80830】Re:十字キーで色をつけたセルの移動の方法
お礼  SHUN  - 19/5/18(土) 12:37 -

引用なし
パスワード
   亀マスターさん

ありがとうございます。
以下のように組んでみたところ、上手くいきました。ありがとうございました。

  i = 10
  j = 10
  
    Cells(i, j).Interior.ColorIndex = 6
    
    
 Do
    '自機発生、操作
    
    If GetAsyncKeyState(37) <> 0 Then
    
    Cells(i, j).Interior.ColorIndex = xlNone
      If j <= 3 Then
      j = 17
      Else
      j = j - 1
      End If
    Cells(i, j).Interior.ColorIndex = 6
    
    End If
    
    If GetAsyncKeyState(38) <> 0 Then
    
    Cells(i, j).Interior.ColorIndex = xlNone
      If i <= 3 Then
      i = 17
      Else
      i = i - 1
      End If
    Cells(i, j).Interior.ColorIndex = 6
    
    End If
    
    If GetAsyncKeyState(39) <> 0 Then
    
    Cells(i, j).Interior.ColorIndex = xlNone
      If j >= 17 Then
      j = 3
      Else
      j = j + 1
      End If
    Cells(i, j).Interior.ColorIndex = 6
    
    End If
    
    If GetAsyncKeyState(40) <> 0 Then
    
    Cells(i, j).Interior.ColorIndex = xlNone
      If i >= 17 Then
      i = 3
      Else
      i = i + 1
      End If
    Cells(i, j).Interior.ColorIndex = 6
    
    End If
    
    If GetAsyncKeyState(13) <> 0 Then
    
    Exit Do
    
    End If
    
  DoEvents
  
  Sleep 90
  
  Loop
  

End Sub
・ツリー全体表示

【80829】Re:フォルダ内のファイル名の変更につい...
発言  γ  - 19/5/18(土) 8:56 -

引用なし
パスワード
   以下のようなコードでステップ実行をするとわかりますが、
getdataが呼ばれるのは一回だけですから、
更新の結果がさらに入力に影響することはあり得ないと思います。

したがって、
一回のループで、1つのファイルに更新が二回されることはないはずです。

Function getdata() As Variant
  Dim fso As New FileSystemObject
  Set getdata = fso.GetFolder("F:\新しいフォルダー").Files
End Function

Sub ファイル名変更()
  Dim myfile As file
  For Each myfile In getdata
    Debug.Print myfile.Name
  Next myfile
End Sub
・ツリー全体表示

【80828】板汚し、更にすみません。
発言  Jaka  - 19/5/18(土) 2:21 -

引用なし
パスワード
   >変えた名前のファイルも新たに拾ってしまうから

これ、右側の文字に関しては当てはまらなかったような?
すみません。
・ツリー全体表示

【80827】ああ、↑ファイル名によってはエラーにな...
発言  Jaka  - 19/5/18(土) 1:26 -

引用なし
パスワード
   ああ、↑ファイル名によってはエラーになります。

エラー処理考えるのが面倒何で、エラーになったらファイル名や文字数が合って無かったのかとか割り切って使ってます。
・ツリー全体表示

【80826】一応使ってるVBS
発言  Jaka  - 19/5/18(土) 1:19 -

引用なし
パスワード
   ちょぼちょぼ修正して、今んところこれで動いているからこれで良いかってやつ。

NowTime = Now()

'VBSファイルのあるフォルダ
Set FSO= CreateObject("Scripting.FileSystemObject")
FPth = FSO.getparentfoldername(wscript.scriptfullname)
'Kakucyoshi = ".png"
Kakucyoshi = ".jpg"
'Kakucyoshi = ".ts"

ALLFCnt = FSO.GetFolder(FPth).Files.Count
'msgbox ALLF_Cnt

'VBSでは、TB(1 to 5)とか、配列の添え字を指定できない。
ReDim ALLF_TB(FSO.GetFolder(FPth).Files.Count)

For Each FFF In FSO.GetFolder(FPth).Files
  If LCase(FSO.GetExtensionName(FFF.Name)) = Mid(Kakucyoshi,2) Then
   'ALLF_TB(cnt) = FSO.GetBaseName(FFF.Name) '拡張子なしのファイル名
   ALLF_TB(cnt) = FFF.Name
   if saisyo_mojisuu > len(FFF.Name) then
     saisyo_mojisuu = len(FFF.Name)
   elseif saidai_mojisuu < len(FFF.Name) then
     saidai_mojisuu = len(FFF.Name)
   end if
   'msgbox ALLF_TB(cnt)
   'WScript.Quit
   cnt = cnt + 1
  End If
Next
'25
KK = inputbox(Kakucyoshi & vblf & vblf & "消去文字数を入力してください","左文字消し",3)
if not isnumeric(KK) then
  msgbox "数字以外",,"中止"
  Set FSO = Nothing
  Erase ALLF_TB
  WScript.Quit
elseif KK = "" then
  msgbox "キャンセル",,"中止"
  Set FSO = Nothing
  Erase ALLF_TB
  WScript.Quit
end if

'文字の長さを比較
'if saidai_mojisuu - KK - len(Kakucyoshi) < len(cnt) then
'  msgbox ""
'end if


'35
'For Each FFF In ALLF_TB 'これだと空っぽ

On Error Resume Next
For i = 0 to cnt - 1
  'msgbox FPth & "\" & ALLF_TB(i)
  'exit for
  Set objFile = FSO.GetFile(FPth & "\" & ALLF_TB(i))
  NewNm = Mid(ALLF_TB(i),KK + 1)
  'msgbox objFile & vblf & NewNm
  if Len(NewNm) < Len(Kakucyoshi) + 1 Then
    Msgbox "削除後の名前に異常あり"& VBlf & VBlf & _
       "削除後の名前 " & NewNm & vblf & _
       "古い名前   " & ALLF_TB(i), _
       vbExclamation,"左文字削除の異常"
    WScript.Quit
  Else
    'if NowTime <= objFile.DateLastModified then
    '  msgbox objFile & " は、名前変更後のファイル。"
    'end if
    'msgbox "更新日時:" & objFile.DateLastModified
    objFile.Name = NewNm
    if err.number <> 0 then
     msgbox "名前変更エラー 元ファイル名" & VBLF &_
         ALLF_TB(i) & VBLF & "変更後ファイル名 " & NewNm
     WScript.Quit
    End if
    Ct = Ct + 1
    'if Ct >=10 then exit for
  End if
Next

Set FSO = Nothing
Set objFile = Nothing
Erase ALLF_TB
msgbox Kakucyoshi & vblf & vblf & "左数文字消し2 「" & KK & "」 文字で終わりました。" & _
    vblf & vblf & Ct & " 個",,"終了"
WScript.Quit
・ツリー全体表示

【80825】Re:フォルダ内のファイル名の変更につい...
発言  Jaka  - 19/5/18(土) 1:00 -

引用なし
パスワード
   >For Each myfile In fso.GetFolder("F:\新しいフォルダー").Files

これねえ、変えた名前のファイルも新たに拾ってしまうから、
最初に全ファイル名を配列に入れて、配列に入れたファイル名を使った方が良いと思います。

vbsで長いこと気付かづ苦労した。
・ツリー全体表示

【80824】Re:十字キーで色をつけたセルの移動の方法
回答  亀マスター  - 19/5/17(金) 23:18 -

引用なし
パスワード
   >”ユーザー定義型が定義されていません”というエラーがでます。

Declare Function から始まるAPIの宣言で、最後に As LongLong としているのが原因です。
LongLongは数値型ですが、これは64bti Officeの環境でしか使えません。
通常は32bitのOfficeを使っていると思われるので、LongLongではなくIntegerを使ってください。

−−−−−−−−−−−−−−−−

なお、それを修正したとしても、いくつか問題が発生することが予想されます。

1.始まるとキーボードの入力を受け付けなくなる
2.1回どれかのキーを押しただけで何十個分も先のセルの色が変わる
3.特定の条件で「アプリケーション定義またはオブジェクトのエラーです」が発生する。

一度実際にやってみて、どんな不具合なのか確認してみることをお勧めしますが、原因と対処法は次のようなものになります。

1.ループを回り続ける間、VBAがパソコンの処理全体を押さえてしまい、他のことができなくなる。
→DoEventsという処理があるので、使い方を調べてみてください。

2.ユーザーは1回だけキーを押したつもりでも、プログラムではループが一瞬で何十周もするので、押していた間にループした回数分だけそのキーが連続で押されたことになる。
→ループのたびに、直前のループでキーが押されていたかどうかをチェックし、押されていればそのループでは処理を行わないようにする。
具体的には、適当な変数(たとえばKeyOn)に、キーが押されたときの処理でTrueを代入し、どのキーも押されていなければFalseを代入する、という処理をとります。

3.変数i、jの値が0以下になった場合に発生します。このとき、Cells(i, j)で0行目や0列目のセルを指定することになるので、そんなものはないからとエラーになるのです。
iやjの値を変更するとき、変更後の結果が0以下になる場合は1にするといった対応が必要です。

以上、実際にやってみてわからないところがあれば、追加で質問してください。
・ツリー全体表示

【80823】Re:[無題]
発言  マナ  - 19/5/17(金) 21:55 -

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

ごめんなさい。毎回ピボットを作り直す必要なかったです。
最初に、手作業で作っておけば、

ws.Cells(9).PivotTable.SourceData = r.Address(, , xlR1C1, True)

これだけで十分でした。
・ツリー全体表示

【80822】Re:VBAでグラフの特定要素を非表示にする
お礼  bonkan  - 19/5/17(金) 20:38 -

引用なし
パスワード
   マナ様
追加ご教示いただきありがとうございます。
リンク先の手順で行なったところ、2013でもコードが記録されました。


返信が遅くなったこをとお詫びいたします。


▼マナ さん:
>▼bonkan さん:
>
>>
>>Office365だとコードが出力されるとのことと追加情報もありがとうございます。
>>エクセル自体のVersionアップも今後は視野に入れていきます。
>
>そうではなくて、「データソーすの選択」画面からだと記録されないのは同じです。
>なので、リンク先の手順ならば、2013でも記録されるのではというつもりでした。
・ツリー全体表示

【80821】Re:[無題]
発言  マナ  - 19/5/17(金) 19:24 -

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

あくまで、たたき台です。
要望と違う部分は、修正してください。

Option Explicit

Sub test2()
  Dim dic As Object
  Dim ws As Worksheet
  Dim c As Range
  Dim e
  Dim n As Long
  Dim r As Range
  Dim fn
  Dim pvt As PivotTable
    
  Set dic = CreateObject("scripting.dictionary")
  
  Set ws = ActiveSheet

  For Each c In ws.Range("a1", ws.Range("a10000").End(xlUp))
    For Each e In Split(c.Offset(, 2).Value, ";")
      n = n + 1
      dic(n) = Array(c.Value, c.Offset(, 1).Value, e)
    Next
  Next
  
  With ws.Cells(5)
    .CurrentRegion.ClearContents
    .Resize(n, 3).Value = Application.Index(dic.items, 0, 0)
    Set r = .CurrentRegion
  End With
  
  fn = Application.Index(r.Value, 1)
  
   With ws.Cells(9)
    On Error Resume Next
    .PivotTable.TableRange2.ClearContents
    On Error GoTo 0
    Set pvt = .Parent.Parent.PivotCaches.Create(xlDatabase, r).CreatePivotTable(.Cells)
  End With

  With pvt
     .RowAxisLayout xlTabularRow
     .RowGrand = False
    .ColumnGrand = False
    
    .AddDataField .PivotFields(fn(2)), fn(2) & " ", xlCount
    .AddFields PageFields:=fn(2), RowFields:=fn(3), ColumnFields:=fn(1)
  
  End With
  
End Sub
・ツリー全体表示

【80820】Re:[無題]
質問  しいな  - 19/5/17(金) 9:16 -

引用なし
パスワード
   ▼マナ さん:
素晴らしいものを作成いただきありがとうございます。
説明不足で申し訳ありません。
A列はピボットの列に指定しております。
本当に申し訳ありません


>▼しいな さん:
>
>>【ピボットテーブル】
>>フィルターにB列
>>行に値
>>値にC列の個数の合計
>>
>>を指定しています。
>
>ピボットで、A列は使用しないということで間違いないですか?
・ツリー全体表示

【80819】Re:[無題]
発言  マナ  - 19/5/16(木) 23:48 -

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

こんな感じで

Option Explicit

Sub test()
  Dim dic As Object
  Dim ws As Worksheet
  Dim c As Range
  Dim e
  Dim n As Long
  Dim r As Range
  Dim fn
  Dim pvt As PivotTable
    
  Set dic = CreateObject("scripting.dictionary")
  
  Set ws = ActiveSheet

  For Each c In ws.Range("B1", ws.Range("B10000").End(xlUp))
    For Each e In Split(c.Offset(, 1).Value, ";")
      n = n + 1
      dic(n) = Array(c.Value, e)
    Next
  Next
  
  With ws.Cells(5)
    .CurrentRegion.ClearContents
    .Resize(n, 2).Value = Application.Index(dic.items, 0, 0)
    Set r = .CurrentRegion
  End With
  
  fn = Application.Index(r.Value, 1)
  
   With ws.Cells(8)
    .PivotTable.TableRange2.ClearContents
    Set pvt = .Parent.Parent.PivotCaches.Create(xlDatabase, r).CreatePivotTable(.Cells)
  End With

  With pvt
     .RowAxisLayout xlTabularRow
    .ColumnGrand = False

    .AddDataField .PivotFields(fn(2)), fn(2) & " ", xlCount
    .AddFields PageFields:=fn(1), RowFields:=fn(2)
  
  End With
  
End Sub
・ツリー全体表示

【80818】Re:フォルダ内のファイル名の変更につい...
発言  γ  - 19/5/16(木) 23:42 -

引用なし
パスワード
   プロシージャの一回の実行で同一ファイルに対し
処理が繰り返されることは無いはずです。
なにか操作ミスで二回実行しているのではないかと思います。
・ツリー全体表示

【80817】Re:[無題]
発言  マナ  - 19/5/16(木) 23:04 -

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

>【ピボットテーブル】
>フィルターにB列
>行に値
>値にC列の個数の合計
>
>を指定しています。

ピボットで、A列は使用しないということで間違いないですか?
・ツリー全体表示

【80816】[無題]
質問  しいな  - 19/5/16(木) 22:14 -

引用なし
パスワード
   Excelのデータを集計し、ピボットテーブルを使用しようと思っています。

【元データ】
A列 結果
B列 ジャンル
C列 名前

となっていて

【ピボットテーブル】
フィルターにB列
行に値
値にC列の個数の合計

を指定しています。
問題は
1.元データのC列に「;」で複数名の名前がある時がある。
→先に元データをコピーして、一人一人のお名前に分ける
2.月によって人数が変わるのにうまくピボットに反映されない

この2点です。
集計数が余りにも多いのでvbaで作りたいと思い
思考錯誤しています
何かいい案はありませんでしょうか?
・ツリー全体表示

【80815】Re:十字キーで色をつけたセルの移動の方法
回答  hatena  - 19/5/16(木) 21:50 -

引用なし
パスワード
   すでに回答で出てますが別案です。

ユーザーフォームを作成します。
名前は、UserForm1 とします。

ユーザーフォームのモジュールを下記のように記述します。

Option Explicit
Dim r As Range

Private Sub UserForm_Initialize()
  Me.StartUpPosition = 0
  Me.Left = 0 - Me.Width - 10
  Set r = Cells(10, 10)
  r.Interior.ColorIndex = 6
End Sub

Private Sub UserForm_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
  Dim r1 As Range
  Set r1 = r
  r1.Interior.ColorIndex = xlNone
  Select Case KeyCode
  Case vbKeyLeft
    If r.Column > 1 Then Set r1 = r.Offset(, -1)
  Case vbKeyUp
    If r.Row > 1 Then Set r1 = r.Offset(-1)
  Case vbKeyRight
    If r.Column < 20 Then Set r1 = r.Offset(, 1)
  Case vbKeyDown
    If r.Row < 20 Then Set r1 = r.Offset(1)
  Case vbKeyEscape
    Unload Me
    Exit Sub
  End Select
  r1.Interior.ColorIndex = 6
  Set r = r1
End Sub


シート上に、ユーザーフォームのボタンを配置して、
下記のマクロを登録します。

Sub ボタン1_Click()
  UserForm1.Show
End Sub

これで、ボタンをクリックすると、Cells(10, 10) が黄色になり、
矢印キーで黄色のセルが移動します。
ESCキーを押すと、終了します。


やっていることは、ユーザーフォームをウィンドウの外に移動させて見えないようにして、
キーボード入力はユーザーフォームで受け取るようにしてます。
・ツリー全体表示

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