Excel VBA質問箱 IV

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

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


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

【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キーを押すと、終了します。


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

【80814】Re:十字キーで色をつけたセルの移動の方法
質問  SHUN  - 19/5/16(木) 20:20 -

引用なし
パスワード
   亀マスターさん
ご回答ありがとうございます。
初心者につき、変数の取得、というのがよくわかっていませんが、色々ググって以下のように修正してみました。
が、”ユーザー定義型が定義されていません”というエラーがでます。
なぜでしょうか?
---
Declare Function GetAsyncKeyState Lib "User32.dll" (ByVal vKey As Long) As LongLong

Sub 練習()

Dim i As Integer

Dim j As Integer


  i = 10
  j = 10
  
    Cells(i, j).Interior.ColorIndex = 6
    
 Do
    If GetAsyncKeyState(37) <> 0 Then
    
    Cells(i, j).Interior.ColorIndex = xlNone
    j = j - 1
    Cells(i, j).Interior.ColorIndex = 6
    
    End If
    
    If GetAsyncKeyState(38) <> 0 Then
    
    Cells(i, j).Interior.ColorIndex = xlNone
    i = i - 1
    Cells(i, j).Interior.ColorIndex = 6
    
    End If
    
    If GetAsyncKeyState(39) <> 0 Then
    
    Cells(i, j).Interior.ColorIndex = xlNone
    j = j + 1
    Cells(i, j).Interior.ColorIndex = 6
    
    End If
    
    If GetAsyncKeyState(40) <> 0 Then
    
    Cells(i, j).Interior.ColorIndex = xlNone
    i = i + 1
    Cells(i, j).Interior.ColorIndex = 6
    
    End If
    
    If GetAsyncKeyState(13) <> 0 Then
    
    Exit Do
    
    End If
    
  Loop
  

End Sub

---

よろしくお願いいたします。

▼亀マスター さん:
>この手のプログラムを組むときは、次のようにループ処理で実現します。
>
>Do
>
>  '押しているキーを取得
>
>  'キーコードに応じた動作
>
>  'ループを抜けるための処理
>
>Loop
>
>現在提示されたコードで問題なのは、
>1.ループしていないのでプログラム中で1回キーコードを判定したら終了する
>2.そもそも入力状況が取得できていない(?)
>
>入力状況の取得方法はいくつかありますが、Windows APIを使うのがわかりやすいと思います。
>ht tps://excel-excel.com/tips/vba_305.html
>
>なお、注意点として、ループ中にループを抜けるためのコードを入れておいてください。でないと、無限ループで終わらなくなります。
>ループを抜ける方法は何でもいいですが、エスケープキーが押されたら抜けるというのがよく見られます。
>If 【エスケープキーが押されている】 Then Exit Do
>という感じにすればいいでしょう。
>
>あと、VBEの設定で「変数の宣言を強制する」にチェックを入れておいた方がいいですよ。
>これを入れておくと、コード中に「Option Explicit」が自動で入り、未定義の変数を使用するとエラーが発生してわかるようになりますが、変数を強制しない状態はバグの温床になります。
>実際、
>Select Case keycode
>の「keycode」って、どこにも宣言してませんよね?
・ツリー全体表示

【80813】Re:十字キーで色をつけたセルの移動の方法
回答  亀マスター  - 19/5/16(木) 19:35 -

引用なし
パスワード
   この手のプログラムを組むときは、次のようにループ処理で実現します。

Do

  '押しているキーを取得

  'キーコードに応じた動作

  'ループを抜けるための処理

Loop

現在提示されたコードで問題なのは、
1.ループしていないのでプログラム中で1回キーコードを判定したら終了する
2.そもそも入力状況が取得できていない(?)

入力状況の取得方法はいくつかありますが、Windows APIを使うのがわかりやすいと思います。
ht tps://excel-excel.com/tips/vba_305.html

なお、注意点として、ループ中にループを抜けるためのコードを入れておいてください。でないと、無限ループで終わらなくなります。
ループを抜ける方法は何でもいいですが、エスケープキーが押されたら抜けるというのがよく見られます。
If 【エスケープキーが押されている】 Then Exit Do
という感じにすればいいでしょう。

あと、VBEの設定で「変数の宣言を強制する」にチェックを入れておいた方がいいですよ。
これを入れておくと、コード中に「Option Explicit」が自動で入り、未定義の変数を使用するとエラーが発生してわかるようになりますが、変数を強制しない状態はバグの温床になります。
実際、
Select Case keycode
の「keycode」って、どこにも宣言してませんよね?
・ツリー全体表示

【80812】十字キーで色をつけたセルの移動の方法
質問  SHUN  - 19/5/16(木) 18:40 -

引用なし
パスワード
   VBA初心者です。

初期位置に黄色で色をつけたセルを、十字キーで押すことにより
移動させるプログラムを組みたいです。(簡単なゲームの自機の操作みたいなイメージです)

以下自作ソースになります。

---

Sub 練習()

Dim i As Integer

Dim j As Integer


  i = 10
  j = 10
  
    Cells(i, j).Interior.ColorIndex = 6
    
  Select Case keycode
    Case vbKeyLeft
    
    Cells(i, j).Interior.ColorIndex = xlNone
    j = j - 1
    Cells(i, j).Interior.ColorIndex = 6
    
    Case vbKeyUp
    
    Cells(i, j).Interior.ColorIndex = xlNone
    i = i - 1
    Cells(i, j).Interior.ColorIndex = 6
    
    Case vbKeyRight
    
    Cells(i, j).Interior.ColorIndex = xlNone
    j = j + 1
    Cells(i, j).Interior.ColorIndex = 6
    
    Case vbKeyDown
    
    Cells(i, j).Interior.ColorIndex = xlNone
    i = i + 1
    Cells(i, j).Interior.ColorIndex = 6
    
  End Select


End Sub

---

初期場所(10,10)を黄色に塗って、例えば左を押したら(10,10)を無色にして
(9,10)に黄色をつけるイメージで作成しましたが、何の反応もありません。

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

【80811】Re:フォルダ内のファイル名の変更につい...
回答  γ  - 19/5/16(木) 7:35 -

引用なし
パスワード
   変更後の名前である
myfile.ParentFolder.Path & "\" & Mid(myfile.Name, InStr(myfile.Name, "☆☆") + 2, 8) & "_" & myfile.Name
について、それぞれの文字列要素
myfile.ParentFolder.Path
Mid(myfile.Name, InStr(myfile.Name, "☆☆") + 2, 8)
myfile.Name
がどのような内容か、ご自分で観察する必要があるのではないですか?
デバッグ手法をおさらいしてください。
・ツリー全体表示

【80810】フォルダ内のファイル名の変更についてで...
質問  チマ  - 19/5/16(木) 6:44 -

引用なし
パスワード
   フォルダ内のファイル名の変更が必要になって次のようなマクロを作成しました

Sub ファイル名変更()
Dim fso As New FileSystemObject
Dim myfile As file
For Each myfile In fso.GetFolder("F:\新しいフォルダー").Files
  If InStr(myfile.Name, "☆☆") <> 0 Then
   fso.MoveFile myfile, myfile.ParentFolder.Path & "\" & Mid(myfile.Name, InStr(myfile.Name, "☆☆") + 2, 8) & "_" & myfile.Name
  End If
Next myfile

End Sub

"F:\新しいフォルダー"の中には
"F:\新しいフォルダー\1234567☆☆1234567891.pdf"
"F:\新しいフォルダー\1234567☆☆12345678912.pdf"
の2つのファイルがありますがマクロの実行結果は

"F:\新しいフォルダー\12345678_12345678_1234567☆☆1234567891.pdf"
"F:\新しいフォルダー\12345678_12345678_1234567☆☆12345678912.pdf"
と書き換わってしまいます。

私はそれぞれ
"F:\新しいフォルダー\12345678_1234567☆☆1234567891.pdf"
"F:\新しいフォルダー\12345678_1234567☆☆12345678912.pdf"
とファイル名を変更したいのですがfor each next で余分にループして思っているファイル名に変更できません。

 いろいろ調べましたがどうしてもわからないので教えてください。
 
・ツリー全体表示

【80809】Re:エラー時のスキップ処理について
お礼  Hiroshi  - 19/5/15(水) 15:44 -

引用なし
パスワード
   ピンクさん

ありがとうございます。

 完璧です。思い通りの作動でした。当初内容が激変していたので戸惑いましたが
アプローチ方法は一つではないと勉強になりました。
・ツリー全体表示

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