Excel VBA質問箱 IV

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

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


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

【78327】Re:「FileSearch」代替クラスの作り方
発言  γ  - 16/7/18(月) 14:36 -

引用なし
パスワード
   書き忘れたけれども、もちろん、こちらでそのコードが
正常に動いていることを確認したうえで、発言しています。

なんらかの環境的なことが悪さをしているものと思います。
それは、そちらで原因追及のトライをしないと分からない性質のものです。
# こちらのテスト実行が不十分の可能性もありますが。
・ツリー全体表示

【78326】Re:「FileSearch」代替クラスの作り方
発言  γ  - 16/7/17(日) 10:28 -

引用なし
パスワード
   ▼Gyouko さん:
>「70:書き込みできません」とのエラーが出力されてしまう。

そのエラーが起きたのはどこの行でしょうか。
ステップ実行して、配下の条件に合致したパス名たちの取得ができているかどうか
確認してください。
そのエラーメッセージだけでは原因がわからないと思います。
・ツリー全体表示

【78325】「FileSearch」代替クラスの作り方
質問  Gyouko  - 16/7/16(土) 16:51 -

引用なし
パスワード
   以下状況にてエラーが発生してしまい苦戦しております。
他力本願で恐縮ですが、どうすれば改善出来るかご教示頂けると幸いです。

<前提>
・社内規定によりエクセルファイルにパスワードを設定。
・内部管理の観点より週次でパスワード有無チェックを実施。
・点検の簡素化のために、退職した前任者がマクロを作成。
・今般、エクセル2003から2013にアップデートしたところ、
 マクロが正常に作動しなくなったので修正したい。

<質問事項>
WEBで調べた結果、Office2007以降FileSearchオブジェクトが
使用不可となった為、作動しなくなったものと思われる為、
以下URLを参考に、クラスモジュールへのインポート及び
「With Application.FileSearch」を「With New FileSearchClass」へ
変更したところ、「70:書き込みできません」とのエラーが出力されてしまう。
d.hatena.ne.jp/xixiixiiixiv/20120806/1344258369

<マクロ>
Option Explicit

Sub samples()
Application.EnableEvents = False
Application.DisplayAlerts = False
ActiveWorkbook.UpdateLinks = xlUpdateLinksNever
Application.ScreenUpdating = False


  Dim f, buf As String, cnt, rc As Long, FSO 'As Object
  Set FSO = CreateObject("Scripting.FileSystemObject")
  With Application.FileSearch
    .NewSearch
    buf = "*.xls"
    If buf = "" Or buf = "False" Then Exit Sub
    .FileName = buf
    buf = GetFolder("検索を開始するフォルダを指定してください")
    If buf = "" Then Exit Sub
    .LookIn = buf
    .SearchSubFolders = True
    If .Execute() > 0 Then
      For Each f In .FoundFiles
        cnt = cnt + 1
        
        rc = kensaku(f)
        Cells(cnt, 1) = f
        If rc = 1 Then
          Cells(cnt, 2) = "パスワード有り"
        Else
          Cells(cnt, 2) = "パスワード無し"
        End If
      
      Next f
    Else
      MsgBox "見つかりませんでした"
    End If
  End With
  Set FSO = Nothing
Application.ScreenUpdating = True

End Sub

Function GetFolder(msg As String)
  Dim Shell, myPath
  Set Shell = CreateObject("Shell.Application")
  Set myPath = Shell.BrowseForFolder(&O0, msg, &H1 + &H10)
  If Not myPath Is Nothing Then
    GetFolder = myPath.Items.Item.Path
  Else
    GetFolder = ""
  End If
  Set Shell = Nothing
  Set myPath = Nothing
End Function


Function kensaku(ByVal f As String) As Integer


Dim xlApp As Application
Dim xlbook As Workbook

Set xlApp = CreateObject("Excel.Application")
Set xlbook = Nothing
On Error Resume Next
Set xlbook = xlApp.Workbooks.Open(f, Password:="", UpdateLinks:=0, ReadOnly:=True, _
       IgnoreReadOnlyRecommended:=True, Notify:=False)
If Err.Number <> 0 Then
If Err.Number = 1004 Then
kensaku = 1
Else
kensaku = 0
Application.DisplayAlerts = False
xlbook.Close savechanges:=False
Application.DisplayAlerts = True
End If
Else
End If
On Error GoTo 0
Application.DisplayAlerts = False
'xlbook.saved =true
xlApp.Quit
Application.DisplayAlerts = True
Set xlApp = Nothing
Set xlbook = Nothing
End Function

Private Sub commanbutton1_click()
Application.Run "点検ツール.xls!sheet1.samples"
End Sub
・ツリー全体表示

【78324】Re:条件付き書式 適用先
発言  β  - 16/7/13(水) 16:30 -

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

>一から設定し直すしかないんですかね


いえいえ。
マクロ記録すると、そういったコードが生成されてしまうということです。
マナさんレスの通りModifyAppliesToRangeを使えばよろしいかと。

たとえば A1 に設定されている条件付書式の適用領域を A1:A100 に変更するなら

Range("A1").FormatConditions(1).ModifyAppliesToRange Range("A1:A100")

と1行でOKだと思います。
・ツリー全体表示

【78323】Re:条件付き書式 適用先
発言  GG  - 16/7/13(水) 16:08 -

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


一から設定し直すしかないんですかね

行追加や
データの削除などしている間に

条件付き書式の設定が多い中
条件付き書式が適用先がバラバラですごいことになっているんで
適用先を修正する物を作りたかったんですが
・ツリー全体表示

【78322】Re:条件付き書式 適用先
発言  β  - 16/7/13(水) 6:49 -

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

失礼します。

亀マスターさんの指摘の通り、マクロ記録すればコード生成されると思いますが?
記録時、マクロの保存先(I) は 「作業中のブック」になっていましたか?

それはさておき、亀マスターさんがアップされたコードは、新規条件設定ではないでしょうか?
すでに設定済みの条件があって、その領域を選択して、適用領域を変更すると
最初に、既存の条件の削除が生成されると思います。

いずれにしても、あらためて、同じ条件で(適用領域だけを変えて)設定するコードになりますね。

マナさんレスのように ModifyAppliesToRange が生成されるとスマートなんですけどね。
・ツリー全体表示

【78321】Re:条件付き書式 適用先
発言  亀マスター  - 16/7/13(水) 0:37 -

引用なし
パスワード
   Excel2013ならマクロ記録で拾えると思うのですがね。

ちなみに、手元のExcel2010でマクロ記録したら次のようなコードになりました。

  Selection.FormatConditions.Add Type:=xlCellValue, Operator:=xlGreater, _
    Formula1:="=100"
  Selection.FormatConditions(Selection.FormatConditions.Count).SetFirstPriority
  With Selection.FormatConditions(1).Font
    .Color = -16383844
    .TintAndShade = 0
  End With
  With Selection.FormatConditions(1).Interior
    .PatternColorIndex = xlAutomatic
    .Color = 13551615
    .TintAndShade = 0
  End With
  Selection.FormatConditions(1).StopIfTrue = False
・ツリー全体表示

【78320】Re:条件付き書式 適用先
発言  マナ  - 16/7/12(火) 20:28 -

引用なし
パスワード
   ▼GG さん:
使ったことありませんが、
ModifyAppliesToRange
で何とかなりませんか?

ht tp://excel-ubara.com/excelvba1/EXCELVBA391.html
・ツリー全体表示

【78319】条件付き書式 適用先
質問  GG  - 16/7/12(火) 12:48 -

引用なし
パスワード
   初めまして

Excel2013
Windows7


条件付き書式 適用先を
VBAで訂正したいのですが
わからず
記録してみましたが
記録にとれませんでした

何か方法、教えて頂きたいのです
よろしくお願いいたします
・ツリー全体表示

【78318】Re:sheet1の商品コードをsheet2に記入さ...
回答  lonelysocrates  - 16/7/4(月) 23:31 -

引用なし
パスワード
   xlFilterValuesはExcel2007で新設された機能です。
Excel2013で試すとこのままで動きました。
・ツリー全体表示

【78317】Re:sheet1の商品コードをsheet2に記入さ...
発言  マルチネス  - 16/6/26(日) 17:05 -

引用なし
パスワード
   本HPの基本ポリシーです。

ht tp://www.vbalab.net/bbspolicy.html
 
>マルチポストについて
>別のサイト(掲示板)にまったく同じ目的の投稿をすることを、一般に「マルチポスト」といいます。当質問箱では、マルチポストは原則認めています。つまり、ほかのサイトで質問したことをこのサイトで質問してもかまわないということです。

>しかし、もしマルチポストをするのなら、可能な限り「○○にも同じ質問を出しました」ということを宣言してください。そして、仮に他のサイトで解決したのなら、ここにも必ずその顛末を書いてください。質問しっぱなし、というのはモラルに反します。「解決したからいいや」というのではありません。

>また、マルチポストを明示的に禁止しているサイトとのマルチポストをしてはいけません。
・ツリー全体表示

【78316】sheet1の商品コードをsheet2に記入されて...
質問  トム  - 16/6/26(日) 10:22 -

引用なし
パスワード
   sheet1の商品コードをsheet2に記入されている商品コードのみ表示したいです。
商品コードは複数あり変更もあるため、動的にフィルターをかけたいのですが、以下のコードだとフィルターがかかりません。
どこが問題でしょうか?

Sub test()

Dim ee As Long
Dim matrix() As String


For ee = 1 To Worksheets("Sheet2").Cells(Rows.Count, "A").End(xlUp).Row
ReDim Preserve matrix(ee - 1)
matrix(ee - 1) = Worksheets("Sheet2").Cells(ee, "A").Value
Next

Worksheets("Sheet1").Activate

Selection.AutoFilter
Range("A1").AutoFilter Field:=1, Criteria1:=matrix, Operator:=xlFilterValues

End Sub
・ツリー全体表示

【78315】Re:Randomwalk
発言  β  - 16/6/24(金) 20:32 -

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

またまたコード不備発見。
A1を左上隅にして実行すれば問題は顕在化しませんが、スクロールされた状態であっても
VisibleRangeを相手にしているのに、その底辺と右端のセットに不備がありました。

Sample/Sample2ともに

  With ActiveWindow.VisibleRange
    t = .Row
    b = .Rows.Count
    l = .Column
    r = .Columns.Count
  End With

これを

  With ActiveWindow.VisibleRange
    t = .Row
    b = .Rows.Count + .Row - 1
    l = .Column
    r = .Columns.Count + .Column - 1
  End With

こうかえてください。
・ツリー全体表示

【78314】Re:Randomwalk
発言  カエムワセト  - 16/6/24(金) 18:36 -

引用なし
パスワード
   >行と列が0にならないようにする処理はβ さんのプログラムではどこに書かれてますか?

まずはβさんのコードの解釈を一行づつ付けて行ってみては?
そうすると自ずと分かってくると思います。
・ツリー全体表示

【78313】Re:Randomwalk
発言  β  - 16/6/24(金) 13:40 -

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

通常、あるセルから1つ移動させるとしたら
左上、上、右上
左、右
左下、下、右下
この8方向ですね。
でも、セルの場所によっては、上にいけない、左にいけないといった制約がある場所がありますね。

で、私のコードでは、左上、上、右上、左、右、左下、下、右下 を 1,2,3,4,5,6,7,8 という番号で指定。
現在のセルの場所に応じて、そのセルから移動できる場所番号を配列に格納。
(場所によって、8か所、5か所、3か所)
pos = Array(5, 7, 8) や pos = Array(1, 2, 4, 6, 7) といったところです。

で、この配列内からランダムに要素を1つ取り出し、1〜8 に応じて、現在の行や列に対して必要な変更を行っています。
Case 1: i = i - 1: j = j - 1 や Case 7: i = i + 1 といったところです。

なので、0 になるのを防ぐというより、最初から候補として、0にならないものに絞っているといったほうが
よろしいかもしれませんね。

そちらのコードの、その部分(0を回避)については 各コードブロックで r と c を求めた後
c が 0 なら c を 1 にする、r が 0 なら r を 1にするといった【逃げ】のコードを追加 といった感じですかね。
これで 0 になってエラーになるのは回避されるでしょうけど、右と下の枠も設定しておかなければ、どんどんと
見えない場所にいってしまいますね。


・ツリー全体表示

【78312】Re:Randomwalk
質問  kinoko  - 16/6/24(金) 12:36 -

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

ありがとうございます。参考になりました。
あと一つだけ聞きたいのですが

行と列が0にならないようにする処理はβ さんのプログラムではどこに書かれてますか?

if do loop 乱数発生 case select 値の入れ替えぐらいしか習っていなくて
これらを駆使して作りたいのですが可能ですか?

何度も質問して申し訳ありません...
・ツリー全体表示

【78311】Re:Randomwalk
発言  β  - 16/6/24(金) 8:54 -

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

アップしたコードにバグありました。
Sample,Sample2 ともに

    If i = l And j = t Then   '領域の左上隅
      pos = Array(5, 7, 8)
    ElseIf i = r And j = t Then '領域の右上隅
      pos = Array(4, 6, 7)

これを

    If i = t And j = l Then   '領域の左上隅
      pos = Array(5, 7, 8)
    ElseIf i = t And j = r Then '領域の右上隅
      pos = Array(4, 6, 7)

にしてください。
・ツリー全体表示

【78310】Re:Randomwalk
発言  β  - 16/6/24(金) 0:46 -

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

>一度通ったところは赤、二度目は青色っていう

ということなら色相返還をしなくてもいいので、アップした、共通モジュールプロシジャは必要なく
以下のみでOKですね。
色の順番は ★のところで規定しています。

Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Private Declare Function GetAsyncKeyState Lib "User32.dll" (ByVal vKey As Long) As Long

Sub Sample2()
  Dim i As Long
  Dim j As Long
  Dim n As Long
  Dim t As Long
  Dim l As Long
  Dim r As Long
  Dim b As Long
  Dim a As Range
  Dim rtn As Long
  Dim pos As Variant
  Dim color As Variant
  
  Cells.Clear
  
  Randomize

  Cells.RowHeight = 5
  Cells.ColumnWidth = 0.5
  
  With ActiveWindow.VisibleRange
    t = .Row
    b = .Rows.Count
    l = .Column
    r = .Columns.Count
  End With
  
  color = Array(vbRed, vbBlue, vbMagenta, vbYellow, vbCyan, vbBlack, vbRed)  '★
  
  '最初のセルを選定
  i = Int((b - t + 1) * Rnd + t)
  j = Int((r - l + 1) * Rnd + l)
  Cells(i, j).Interior.color = vbRed
  
  Do
    
    rtn = GetAsyncKeyState(16) 'シフトキー
    rtn = rtn And &H80000000
    If rtn <> 0 Then Exit Do
    
    If i = l And j = t Then   '領域の左上隅
      pos = Array(5, 7, 8)
    ElseIf i = r And j = t Then '領域の右上隅
      pos = Array(4, 6, 7)
    ElseIf i = b And j = l Then '領域の左下隅
      pos = Array(2, 3, 5)
    ElseIf i = b And j = r Then '領域の右下隅
      pos = Array(1, 2, 6)
    ElseIf i = t Then      '領域の上辺
      pos = Array(4, 5, 6, 7, 8)
    ElseIf i = b Then      '領域の下辺
      pos = Array(1, 2, 3, 4, 5)
    ElseIf j = l Then      '領域の左端
      pos = Array(2, 3, 5, 7, 8)
    ElseIf j = r Then      '領域の右端
      pos = Array(1, 2, 4, 6, 7)
    Else
      pos = Array(1, 2, 3, 4, 5, 6, 7, 8)
    End If
    
    n = Int((UBound(pos) - LBound(pos) + 1) * Rnd + LBound(pos))
    n = pos(n)
    
    'セル移動
    Select Case n
      Case 1: i = i - 1: j = j - 1
      Case 2: i = i - 1
      Case 3: i = i - 1: j = j + 1
      Case 4: j = j - 1
      Case 5: j = j + 1
      Case 6: i = i + 1: j = j - 1
      Case 7: i = i + 1
      Case 8: i = i + 1: j = j + 1
    End Select
    
    With Cells(i, j).Interior
      If .ColorIndex = xlNone Then
        .color = vbRed     '最初は赤
      Else
        n = WorksheetFunction.Match(.color, color, 0)
        .color = color(n)
      End If
    End With
    
    Sleep 10
    DoEvents
    
  Loop
  
End Sub
・ツリー全体表示

【78309】Re:Randomwalk
回答  kinoko  - 16/6/24(金) 0:03 -

引用なし
パスワード
   >壁 とは 具体的にどこを想定されています?
>PC画面に見えている範囲のことですか?

説明を忘れていました。行や列が0をせずになんとか止まらず動かしていきたいって感じです。壁というのは行と列ですね。申し訳ないです。

>色を変えていく処理
>どんなように変化させていきたいですか?

一度通ったところは赤、二度目は青色っていう風にしてみたいんですけど、まず0になってエラー吐くんでできてないんですよね…
・ツリー全体表示

【78308】Re:Randomwalk
発言  β  - 16/6/23(木) 21:48 -

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

私も一例を。

動きの枠を、今、デスクトップに表示されているエクセルシートの範囲にしています。
ただし、かなり細かなマス目にしてありますよね。【壁】には、なかなか到達しないかもしれません。
気長に眺めていれば、いつかは壁にぶつかって、壁の外にはいかない動きをします。

すでに通り過ぎて色がついているセルについては、HSV色相で左回りに10°ずつ、色を変化させています。
h tps://ja.wikipedia.org/wiki/%E8%89%B2%E7%9B%B8

なお、HSV色相に関してはVBAでは標準の変換関数がないので自前で共通プロシジャとして使っているものを
使います。

Shiftキーを眺めに押せば、終了します。

●テストモジュール

Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Private Declare Function GetAsyncKeyState Lib "User32.dll" (ByVal vKey As Long) As Long

Sub Sample()
  Dim i As Long
  Dim j As Long
  Dim n As Long
  Dim t As Long
  Dim l As Long
  Dim r As Long
  Dim b As Long
  Dim a As Range
  Dim rtn As Long
  Dim d As HSVSET
  Dim pos As Variant
  
  Cells.Clear

  Randomize

  Cells.RowHeight = 5
  Cells.ColumnWidth = 0.5
  
  With ActiveWindow.VisibleRange
    t = .Row
    b = .Rows.Count
    l = .Column
    r = .Columns.Count
  End With
  
  '最初のセルを選定
  i = Int((b - t + 1) * Rnd + t)
  j = Int((r - l + 1) * Rnd + l)
  Cells(i, j).Interior.Color = vbRed
  
  Do
    
    rtn = GetAsyncKeyState(16) 'シフトキー
    rtn = rtn And &H80000000
    If rtn <> 0 Then Exit Do
    
    If i = l And j = t Then   '領域の左上隅
      pos = Array(5, 7, 8)
    ElseIf i = r And j = t Then '領域の右上隅
      pos = Array(4, 6, 7)
    ElseIf i = b And j = l Then '領域の左下隅
      pos = Array(2, 3, 5)
    ElseIf i = b And j = r Then '領域の右下隅
      pos = Array(1, 2, 6)
    ElseIf i = t Then      '領域の上辺
      pos = Array(4, 5, 6, 7, 8)
    ElseIf i = b Then      '領域の下辺
      pos = Array(1, 2, 3, 4, 5)
    ElseIf j = l Then      '領域の左端
      pos = Array(2, 3, 5, 7, 8)
    ElseIf j = r Then      '領域の右端
      pos = Array(1, 2, 4, 6, 7)
    Else
      pos = Array(1, 2, 3, 4, 5, 6, 7, 8)
    End If
    
    n = Int((UBound(pos) - LBound(pos) + 1) * Rnd + LBound(pos))
    n = pos(n)
    
    'セル移動
    Select Case n
      Case 1: i = i - 1: j = j - 1
      Case 2: i = i - 1
      Case 3: i = i - 1: j = j + 1
      Case 4: j = j - 1
      Case 5: j = j + 1
      Case 6: i = i + 1: j = j - 1
      Case 7: i = i + 1
      Case 8: i = i + 1: j = j + 1
    End Select
    
    With Cells(i, j).Interior
      If .ColorIndex = xlNone Then
        .Color = vbRed     '最初は赤
      Else
        d = RGB2HSV(.Color)
        d.h = d.h + 10     '次からは色相を10°左回りに移動した色
        .Color = HSV2RGB(d)
      End If
    End With
    
    Sleep 10
    DoEvents
    
  Loop
  
End Sub

●共通プロシジャモジュール

Public Type HSVSET
  h As Double
  s As Double
  v As Double
End Type

Public Type RGBSET
  r As Long
  g As Long
  b As Long
End Type

Function RGB2HSV(rgbVal As Long) As HSVSET
  Dim mx As Long
  Dim mn As Long
  Dim r As Long
  Dim g As Long
  Dim b As Long
  Dim z As RGBSET
  
  z = divRGB(rgbVal)
  
  r = z.r
  g = z.g
  b = z.b
  
  mn = WorksheetFunction.Min(r, g, b)
  mx = WorksheetFunction.Max(r, g, b)
  
  If mx = mn Then
    RGB2HSV.h = 0
  Else
    Select Case mx
      Case r
        RGB2HSV.h = (60 * (g - b) / (mx - mn) + 360)
        If (RGB2HSV.h >= 360#) Then
          RGB2HSV.h = RGB2HSV.h - 360#
        End If
      Case g
        RGB2HSV.h = 60 * (b - r) / (mx - mn) + 120
      Case b
        RGB2HSV.h = 60 * (r - g) / (mx - mn) + 240
    End Select
  End If
  
  If mx = 0 Or mx = mn Then
    RGB2HSV.s = 0
  Else
    RGB2HSV.s = 255 * ((mx - mn) / mx)
  End If
  
  RGB2HSV.v = mx
  
End Function

Function HSV2RGB(d As HSVSET) As Long
  Dim r As Long
  Dim g As Long
  Dim b As Long
  Dim f As Double
  Dim i As Long
  Dim p As Long
  Dim q As Long
  Dim t As Long
  Dim h As Double
  Dim s As Double
  Dim v As Double
 
  If d.s = 0 Then
    r = d.v
    g = d.v
    b = d.v
  Else
    h = d.h
    s = d.s
    v = d.v
    If h = 360 Then h = 0
    i = Int(h / 60) Mod 6
    f = h / 60 - Int(h / 60)
    p = Int(CInt(v * (1 - (s / 255))))
    q = Int(CInt(v * (1 - (s / 255) * f)))
    t = Int(CInt(v * (1 - ((s / 255) * (1 - f)))))
    
    Select Case i
      Case 0: r = v: g = t: b = p
      Case 1: r = q: g = v: b = p
      Case 2: r = p: g = v: b = t
      Case 3: r = p: g = q: b = v
      Case 4: r = t: g = p: b = v
      Case 5: r = v: g = p: b = q
    End Select
  End If
  
  HSV2RGB = RGB(r, g, b)
  
End Function

Function divRGB(rgbVal As Long) As RGBSET
  divRGB.b = rgbVal \ 256 ^ 2
  divRGB.g = (rgbVal - divRGB.b * 256 ^ 2) \ 256
  divRGB.r = rgbVal - divRGB.b * 256 ^ 2 - divRGB.g * 256
End Function
・ツリー全体表示

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