Excel VBA Sample 8
▼リボンを非表示にするコード
Application.ExecuteExcel4Macro "SHOW.TOOLBAR(""Ribbon"",False)"
上記のコードを実行するとリボンが非表示になります。
逆にリボンを表示するときは、以下のコードを実行してください。
▼リボンを表示するコード
Application.ExecuteExcel4Macro "SHOW.TOOLBAR(""Ribbon"",True)"
■リボンをカスタマイズするXML
'ZIP解凍したxlsm の中にcustomUIフォルダを作成してcustomUI.xmlをutf-8 で作成。
_rels/.rels ファイルを以下手順で編集し、再ZIPして拡張子をxlsmに戻してやれば完成
customUI.xml 2007用
-------------
<?xml version="1.0" encoding="utf-8"?>
<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui">
<ribbon startFromScratch="false">
<tabs>
<tab id="tab2007" label="Tab 2007">
<group id="grp2007" label="Group 2007">
<button id="btn2007" label="Button 2007" imageMso="HappyFace" size="large" onAction="Macro2007" />
</group>
</tab>
</tabs>
</ribbon>
</customUI>
customUI14.xml 2010~用
-------------
<?xml version="1.0" encoding="utf-8"?>
<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui">
<ribbon startFromScratch="false">
<tabs>
<tab id="tab2010" label="Tab 2010">
<group id="grp2010" label="Group 2010">
<button id="btn2010" label="Button 2010" imageMso="SadFace" size="large" onAction="Macro2010" />
</group>
</tab>
</tabs>
</ribbon>
</customUI>
用意するコールバック関数'Thisworkbookモジュールに書いて
onAction="Macro2010" 部分を onAction="Thisworkbook.Macro2010" と書いてやると
Private で宣言できる。
Public Sub Macro2007(control As IRibbonControl)
MsgBox "Hello! 2007!!", vbExclamation
End Sub
Public Sub Macro2010(control As IRibbonControl)
MsgBox "Hello! 2010!!", vbCritical
End Sub
「_rels」フォルダにある「.rels」ファイル
</Relationships>」の前に下記のコードを貼り付け、上書き保存します。
<Relationship Id="myCustomUI" Type="http://schemas.microsoft.com/office/2006/relationships/ui/extensibility" Target="/customUI/customUI.xml" />
◆貼り付けを値貼り付けに強制する
'↓いい線いっているんだけど、EnterKeyでも貼り付けできちゃうので
不完全。むずかしいや。⇒こんな事をしなくても、シートに保護をかければ値貼り付けにはなる。
ただし、入力規則のチェックは利かないのが残念なところ。一セルずつChangeイベントで値をチェックしないと
完璧ではない。
Option Explicit
'Thisworkbookモジュール
'このサンプルはSheet1の入力規則セルへのコピペを
'値貼り付け以外禁止し、値貼り付けも入力規則にあわない物は
'制限します。
''いい感じに出来たとおもったんだけど、Enterキーでも
''貼り付けできちゃうのでボツにしたコード
Private WithEvents BtnPasteSpecial As Office.CommandBarButton
Private WithEvents BtnPasteAll As Office.CommandBarButton
Sub ignition()
'形式を選択して貼り付け
Set BtnPasteSpecial = Application.CommandBars.FindControl(, 755)
'貼り付け
Set BtnPasteAll = Application.CommandBars.FindControl(, 22)
End Sub
Private Sub LetPasteValue(Optional NotSendV As Boolean, Optional CancelDefault As Boolean)
'Microsoft Forms2.0 object Library参照設定要
'ActiveXコントロールが挿入されているブックであれば
'この参照設定は自動で入る。
Dim myData As New DataObject
Dim cpytxt As String
Dim aryStr As Variant
Dim flgOK As Boolean
Dim i As Long
Const textFormat As Long = 1
On Error GoTo err_handle
If ActiveWorkbook Is ThisWorkbook Then
If _
ActiveSheet Is Sheet1 Then
'入力規則がある場合
If HasValidation(ActiveCell) Then
myData.GetFromClipboard
cpytxt = myData.GetText(textFormat)
cpytxt = Replace(cpytxt, vbTab, vbNullString)
cpytxt = Replace(cpytxt, vbCr, vbNullString)
cpytxt = Replace(cpytxt, vbLf, vbNullString)
With ActiveCell.Validation
aryStr = .Formula1
aryStr = Split(aryStr, ",")
End With
For i = 0 To UBound(aryStr)
If cpytxt = aryStr(i) Then
flgOK = True
Exit For
End If
Next
If flgOK = False Then
Err.Raise _
1 + vbObjectError, "LetPasteValue", _
"このセルには " & Join(aryStr, " , ") & " のみ貼り付けできます"
End If
End If
ActiveCell.PasteSpecial xlPasteValues
CancelDefault = True
Else
'Ctrl+V の場合
If NotSendV = False Then
ActiveCell.PasteSpecial
End If
End If
End If
end_handle:
Exit Sub
err_handle:
MsgBox Err.Description, vbExclamation, ThisWorkbook.Name
Resume end_handle
End Sub
'セルが入力規則を持っていればTrue
Private Function HasValidation(rng As Range) As Boolean
Dim v
On Error Resume Next
v = rng.Validation.Formula1
If Err.Number = 0 Then
HasValidation = True
End If
On Error GoTo 0
End Function
Private Sub BtnPasteSpecial_Click(ByVal Ctrl As Office.CommandBarButton, CancelDefault As Boolean)
Call LetPasteValue(True, CancelDefault)
End Sub
Private Sub BtnPasteAll_Click(ByVal Ctrl As Office.CommandBarButton, CancelDefault As Boolean)
Call LetPasteValue(True, CancelDefault)
End Sub
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Application.ExecuteExcel4Macro "SHOW.TOOLBAR(""Ribbon"",True)"
'カスタムキーの復帰
Application.OnKey "^v"
Application.OnKey "^{down}"
End Sub
Private Sub Workbook_Open()
Call ignition
End Sub
Private Sub SelectValidation()
Dim aryStr As Variant
Dim ary As Variant
Static i As Long
'入力規則がある場合
If HasValidation(ActiveCell) Then
With ActiveCell.Validation
aryStr = .Formula1
ary = Split(aryStr, ",")
End With
ActiveCell.Value = ary(i Mod (UBound(ary) + 1))
i = i + 1
Else
ActiveCell.End(xlDown).Select
End If
End Sub
Private Sub Workbook_SheetActivate(ByVal Sh As Object)
If Sh Is Sheet1 Then
Application.ExecuteExcel4Macro "SHOW.TOOLBAR(""Ribbon"",False)"
Application.OnKey "^v", Me.CodeName & ".LetPasteValue"
Application.OnKey "^{down}", Me.CodeName & ".SelectValidation"
Else
Application.ExecuteExcel4Macro "SHOW.TOOLBAR(""Ribbon"",True)"
'カスタムキーの復帰
Application.OnKey "^v"
Application.OnKey "^{down}"
End If
End Sub
'■クリップボードを空にする
Sub 処理()
Sheet2.Copy Sheet1
'↓これ入れておくと閉じる時「保存しますか?」とは訊いてきても
'クリップボードに大きな情報があります。どーしますか?とは訊かれないで済む
Application.CutCopyMode = False
End Sub
'■ユーザー定義関数 カンマ区切りの文字列長不定で先頭が "0" で始まるかもしれない
'数字文字列を 数字として並び替えて表示する
'sample =csvSort("05"&",09, 003, 00200, 0001,111",TRUE) ⇒ 01, 03, 005, 00009, 0111, 200
'桁が一緒に並び変わらないのでダメだこれは… むずかしい
'文字列長不定の"0"から始まる事もある数字文字列を数字としてソートして返します。
Function csvSort(csv As String, Optional asc As Boolean = True) As String
Dim ary As Variant
Dim cl As Collection
ary = Split(csv, ",")
Set cl = cnvLng(ary)
Dim i As Long
For i = 0 To cl.Count - 1
ary(i) = Format$(cl.Item(i + 1)(0), String(15, "0"))
Next
Call ArySort(ary, LBound(ary), UBound(ary), asc)
Dim rslt As String
For i = LBound(ary) To UBound(ary)
rslt = rslt & ", " & Format$(CLng(ary(i)), String(cl.Item(i + 1)(1), "0"))
Next
csvSort = Right$(rslt, Len(rslt) - 2)
End Function
Private Function cnvLng(ary As Variant) As Collection
Dim i As Long
Dim trimAry As String
Dim cl As New Collection
For i = LBound(ary) To UBound(ary)
trimAry = Trim(ary(i))
cl.Add Array(CLng(trimAry), Len(trimAry))
Next
Set cnvLng = cl
End Function
'■ファイルが開いているか否かを判定する
Option Explicit
'ブックが開いているか開いていないかのチェック
Function IsWbOpen(WbfullPth As String) As Boolean
'ファイルが存在しない場合はエラー
'うっかりAppendモードでOpenすると
'新規ファイルが作成されてしまう。
If CreateObject("Scripting.FileSystemObject"). _
FileExists(WbfullPth) = False Then
Err.Raise 514, , WbfullPth & " は存在しません"
End If
'追加モードでファイルを開く
'ブックとして開いてReadOnlyプロパティを
'確認するよりも高速に判断できる
On Error Resume Next
Open WbfullPth For Append As #1
Close #1
If Err.Number Then
IsWbOpen = True
Else
IsWbOpen = False
End If
End Function
'■'全テキストカナ表示に変換。漢字があればヨミに変換します
'range("a1") が "カタカナ漢字ひらがな" なら "カタカナカンジヒラガナ" と変換できます
Function cnvStrKanaAll(rng As Range, mode As VbStrConv) As String
If Len(rng.Value) = 0 Then
cnvStrKanaAll = vbNullString
Else
rng.SetPhonetic
Dim v As Phonetics
Dim y As Phonetics
Dim s As String
Dim i As Long
Dim yomicl As New Collection
Dim ymCnt As Long
Set v = rng.Phonetics
For Each y In v
yomicl.Add Array(y.Text, y.Length)
Next
For i = 1 To Len(rng.Text)
'"亜"はShiftJisでの漢字の最小
'"亜"より小さいcodeの文字を「記号」とみなす
If Hex(Asc(Mid$(rng.Text, i, 1))) < Hex(Asc("亜")) Then
s = s & Mid$(rng.Text, i, 1)
Else
ymCnt = ymCnt + 1
s = s & yomicl.Item(ymCnt)(0)
i = i + yomicl.Item(ymCnt)(1) - 1
End If
Next
cnvStrKanaAll = StrConv(s, mode)
End If
End Function
'■文字コードに関するあれこれ
Option Explicit
'文字コードの列挙体
Public Enum chrCodes
unicode = 1
shift_jis = 2
jis = 3
End Enum
'進数の列挙体
Enum shinSuu
e_binary = 2
e_oct = 8
e_hex = 16
End Enum
Private m_2shin As String '"(2進)"
Private m_8shin As String 'Chr(38) & "0"
Private m_16shin As String 'Chr(38) & "H"
'Microsfot VBScript Regular ExpressionsX.X 要参照設定
Private instReg As VBScript_RegExp_55.RegExp
'ユーザー定義関数、数式パレット上の説明
Public Sub SetHelpDescription()
'GetCodeFromChar
Application.MacroOptions _
macro:="GetCodeFromChar", _
Category:="文字コード・進数変換", _
Description:= _
"指定文字コードでGlyph(文字)に対応する10進数を返します。" & vbNewLine & _
"第2引数には、Unicode:1, Shift_Jis:2, Jis:3 を指定して下さい"
'GetCharFromCode
Application.MacroOptions _
macro:="GetCharFromCode", _
Category:="文字コード・進数変換", _
Description:= _
"10進数値を指定文字コードでGlyphを返します。" & _
"16進数にはプリフィックス &H を付けて指定します。" & vbNewLine & _
"第2引数には、unicode:1, shift_JIS:2, jis:3 の何れかを指定します。"
'GetAdicNumber
Application.MacroOptions _
macro:="GetAdicNumber", _
Category:="文字コード・進数変換", _
Description:= _
"10進数を渡して2,8,16進数を返します。" & _
"第2引数に、2, 8, 16 の何れかを指定します" & _
"戻り値は32ビットの正の整数表現になります。" & vbNewLine & _
"例:GetAdicNumber(-1, 16) ⇒ '&HFFFFFFFF'"
'GetDecNumFromAdic
Application.MacroOptions _
macro:="GetDecNumFromAdic", _
Category:="文字コード・進数変換", _
Description:= _
"2,8,16進数をを渡してLong型の10進数を返します。" & vbNewLine & _
"第2引数に、2, 8, 16 の何れかを指定します" & _
"第1引数にはセルの番地で指定するか文字列を渡して下さい" & vbNewLine & _
"例:GetDecNumFromAdic(""FFFFFFFF"", 16) ⇒ -1"
'IsGaiji
Application.MacroOptions _
macro:="IsGaiji", _
Category:="文字コード・進数変換", _
Description:= _
"文字を渡し、外字であれば TRUE を返します。" & vbNewLine & _
"Shift_JIS以外の文字であれば 'NotShift_JIS' を返します。"
m_2shin = "(2進)"
m_8shin = "&0"
m_16shin = "&H"
End Sub
'10進数値を指定文字コードでGlyphを返します。
'16進数にはプリフィックス &H を付けて指定します。
'第2引数には、unicode:1, shift_JIS:2, jis:3 の何れかを指定します。
Function GetCharFromCode(ByRef decNum As Long, ByRef code As chrCodes) As String
Select Case code
Case unicode
GetCharFromCode = VBA.ChrW(decNum)
Case shift_jis
GetCharFromCode = VBA.Chr(decNum)
Case jis
GetCharFromCode = Evaluate("char(" & decNum & ")")
Case Else
'何もしない
End Select
End Function
'指定文字コードでGlyphに対応する10進数を返します。
'第2引数には、Unicode:1, Shift_Jis:2, Jis:3 を指定して下さい
Function GetCodeFromChar(ByRef myChr As String, ByRef code As chrCodes) As Long
Select Case code
Case unicode
GetCodeFromChar = VBA.AscW(myChr)
Case shift_jis
GetCodeFromChar = VBA.Asc(myChr)
Case jis
GetCodeFromChar = Evaluate("code(""" & myChr & """)")
Case Else
'何もしない
End Select
End Function
'10進数を渡して2,8,16進数を返します。
'第2引数に、2, 8, 16 の何れかを指定します
Function GetAdicNumber(ByRef decNum As Long, ByRef num_adic As shinSuu) As String
Dim strNum As String
Dim str1Keta As String
Dim strBinNum As String
Dim preFix As String
Dim i As Long
'ひとまず16進に変換
strNum = Hex(decNum)
Select Case num_adic
Case e_binary
preFix = m_2shin
strBinNum = ""
For i = 1 To Len(strNum)
str1Keta = Mid$(strNum, i, 1)
Select Case str1Keta
Case "0"
strBinNum = strBinNum & "0000"
Case "1"
strBinNum = strBinNum & "0001"
Case "2"
strBinNum = strBinNum & "0010"
Case "3"
strBinNum = strBinNum & "0011"
Case "4"
strBinNum = strBinNum & "0100"
Case "5"
strBinNum = strBinNum & "0101"
Case "6"
strBinNum = strBinNum & "0110"
Case "7"
strBinNum = strBinNum & "0111"
Case "8"
strBinNum = strBinNum & "1000"
Case "9"
strBinNum = strBinNum & "1001"
Case "A"
strBinNum = strBinNum & "1010"
Case "B"
strBinNum = strBinNum & "1011"
Case "C"
strBinNum = strBinNum & "1100"
Case "D"
strBinNum = strBinNum & "1101"
Case "E"
strBinNum = strBinNum & "1110"
Case "F"
strBinNum = strBinNum & "1111"
End Select
Next
'先頭の 0 を除去
Do While Left$(strBinNum, 1) = 0
strBinNum = Right$(strBinNum, Len(strBinNum) - 1)
If Len(strBinNum) = 1 Then Exit Do
Loop
strNum = strBinNum
Case e_oct
preFix = m_8shin
strNum = Oct("&H" & strNum)
Case e_hex
preFix = m_16shin
'そのまんま
Case Else
Err.Raise 513, , "GetAdicNumber の第2引数には" & _
shinSuu.e_binary & ", " & shinSuu.e_oct & ", " & shinSuu.e_hex & _
" の何れかを指定します"
Exit Function
End Select
GetAdicNumber = preFix & strNum
End Function
'2,8,16進数をを渡して10進数を返します。
'第2引数に、2, 8, 16 の何れかを指定します
Function GetDecNumFromAdic(ByRef adicNum As String, ByRef mode As shinSuu) As Long
Dim rsltNum As Long
Dim minusFlg As Boolean
'途中 Like 演算子で引数のチェックをしているので
'a も Aと同じに扱われるように全て大文字にしておく
adicNum = VBA.StrConv(adicNum, vbUpperCase)
Set instReg = New VBScript_RegExp_55.RegExp
Select Case mode
Case e_binary
'引数チェック
Do While Left$(adicNum, 1) Like "[!0-1]"
adicNum = Right$(adicNum, Len(adicNum) - 1)
Loop
'先頭の 0 は除く
Do While Left$(adicNum, 1) = "0"
adicNum = Right$(adicNum, Len(adicNum) - 1)
Loop
With instReg
.Pattern = "[^0-1]"
.Global = True
.IgnoreCase = False
If .Test(adicNum) Then
Err.Raise 514, , _
"文字列の先頭部分以外に、" & _
"2進数にない値が含まれています"
End If
End With
If Len(adicNum) > 32 Then
Err.Raise 6 'オーバーフロー
End If
If Len(adicNum) = 0 Then
Err.Raise 515, , "8進数ではありません。"
End If
Dim i As Long
'マイナス判定
If Len(adicNum) = 32 And Left$(adicNum, 1) = "1" Then
minusFlg = True
adicNum = Right$(adicNum, Len(adicNum) - 1)
End If
For i = 1 To Len(adicNum)
'マイナスの最大値絶対値が1大きいので
'オーバーフローしないように符号をマイナスにしておく。
rsltNum = _
rsltNum - CLng(Mid$(adicNum, i, 1)) * (2 ^ (Len(adicNum) - i))
Next
'符号を戻す
If minusFlg Then
'既にマイナスに算出しているので符号の変更はないが、
'負数の場合 -1 する。
'同一ビット1111111 11111111 11111111 11111111(DF FF FF FF)でも
'正に解釈すると 0~2^32-1 になり、
'負に解釈すると-(1~2^32) であり調整が必要。
rsltNum = rsltNum - 1
Else
rsltNum = -rsltNum
End If
Case e_oct
'文字列の先頭部分から8進数以外を排除
Do While Left$(adicNum, 1) Like "[!0-7]"
adicNum = Right$(adicNum, Len(adicNum) - 1)
Loop
'引数チェック
With instReg
.Pattern = "[^0-7]"
.Global = True
.IgnoreCase = False
If .Test(adicNum) Then
Err.Raise 516, , "文字列の先頭部分以外に" & _
" 8 進数でない値があります。"
End If
End With
If Len(adicNum) = 0 Then
Err.Raise 517, , "8進数ではありません。"
End If
rsltNum = "&0" & adicNum
Case e_hex
'文字列先頭部分に16進の数字以外の値があれば排除
Do While Left$(adicNum, 1) Like "[!0-9, !A-F]"
adicNum = Right$(adicNum, Len(adicNum) - 1)
Loop
'引数チェック
With instReg
.Pattern = "[^0-9, ^A-F]"
.Global = True
.IgnoreCase = False
If .Test(adicNum) Then
Err.Raise 516, , "文字列先頭部分以外に" & _
" 16進数でない値があります。"
End If
End With
If Len(adicNum) > 8 Then
Err.Raise 6 'オーバーフロー
End If
If Len(adicNum) = 0 Then
Err.Raise 517, , "16進数ではありません。"
End If
rsltNum = "&h" & adicNum
End Select
GetDecNumFromAdic = rsltNum
End Function
'文字を渡し、外字であれば TRUE を返す
'Windowsのユーザー外字領域(Shift_JIS)
'0xF040(61504)-0xF9FC(63996)
'文字を渡し、Shift_JIS以外の文字であれば"NotShift_JIS"を返す
Function IsGaiji(myChar As String) As Variant
Dim ret As Long
Const Maxcode As Long = 63996
Const mincode As Long = 61504
ret = Asc(myChar)
'Shift_JISに無い文字はchr(63):"?"が返る
If ret = 63 Then
If myChar <> "?" Then
IsGaiji = "NotShift_JIS"
End If
Exit Function
End If
If ret >= mincode And ret <= Maxcode Then
IsGaiji = True
Else
IsGaiji = False
End If
End Function
'/文字コードに関するあれこれ
'■参照設定する
Sub 参照設定を調べる()
'これでGUIIDが判るので
'[Microsoft Visual Basic for Applications Extensibility] に参照設定
Dim ref As Reference
For Each ref In ThisWorkbook.VBProject.References
With ref
Debug.Print _
.Name & vbCrLf & _
.Description & vbCrLf & _
.FullPath & vbCrLf & _
.guid & vbCrLf & _
TypeName(ref) & vbCrLf & _
"----"
End With
Next ref
'Excel
'Microsoft Excel 12.0 Object Library
'C:\Program Files (x86)\Microsoft Office\Office12\EXCEL.EXE
'{00020813-0000-0000-C000-000000000046}
'Reference
'----
'stdole
'OLE Automation
'C:\Windows\SysWOW64\stdole2.tlb
'{00020430-0000-0000-C000-000000000046}
'Reference
'----
'Office
'Microsoft Office 12.0 Object Library
'C:\Program Files (x86)\Common Files\Microsoft Shared\OFFICE12\MSO.DLL
'{2DF8D04C-5BFA-101B-BDE5-00AA0044DE52}
'Reference
'----
'Scripting
'Microsoft Scripting Runtime
'C:\Windows\SysWOW64\scrrun.dll
'{420B2830-E718-11CF-893D-00A0C9054228}
'Reference
'----
'VBIDE
'Microsoft Visual Basic for Applications Extensibility 5.3
'C:\Program Files (x86)\Common Files\Microsoft Shared\VBA\VBA6\VBE6EXT.OLB
'{0002E157-0000-0000-C000-000000000046}
'Reference
'----
End Sub
'参照設定を追加するマクロ
Sub AddReference()
'これでScriptingRuntimeに参照設定が入る
Const cnScritingRunTime As String = "{420B2830-E718-11CF-893D-00A0C9054228}"
ThisWorkbook.VBProject.References.AddFromGuid cnScritingRunTime, 1, 0
End Sub
'■ワークシート上のActiveXオブジェクトのプロパティ操作
Sub コンボボックスのプロパティテスト()
Dim cmb As MSForms.ComboBox
Dim ole As OLEObject
For Each ole In OLEObjects
Set cmb = ole.Object
cmb.Style = fmStyleDropDownList
cmb.List = Array("1", "2", "3")
cmb.Enabled = True
Next
For Each ole In OLEObjects
Set cmb = ole.Object
cmb.Locked = True
'あれ?利くぞ???xl2007
Next
End Sub
Sub テキストボックスのプロパティテスト()
Dim txb As MSForms.TextBox
Dim ole As OLEObject
For Each ole In OLEObjects
Set txb = ole.Object
txb.Enabled = True
Next
For Each ole In OLEObjects
Set txb = ole.Object
txb.Locked = True
'ああああああああああああああああああ利く@xl2007
Ne
End Sub
'大量のワークシート作成でリソース不足に陥れないアイディア
'シートのカウント管理とカウントを監視して50シート超え
'イベントを検知するイベントを作って対処すれば、混乱せずに
'コーディングできる。。。という作戦
Sub test()
Dim i As Long, j As Long
Dim shNameAry(29) As Worksheet
For i = 1 To 400
Sheet1.Copy after:=Sheet1
'50シート超えたら30シートずつ別ブックに保存させて
'リソース不足を凌ぐ作戦
If ThisWorkbook.Sheets.Count > 50 Then
For i = LBound(shNameAry) To UBound(shNameAry)
shNameAry(i) = ThisWorkbook.Worksheets(i).Name
Next
'新規ブックに移動
ThisWorkbook.Worksheets(shNameAry).Copy
'With ActiveWorkbook
' .SaveAs EnebleWbPath
' .Close
'End With
'Application.DisplayAlerts=False
'ThisWorkbook.Worksheets(shNameAry).delete
'Application.DisplayAlerts = True
End If
Next
End Sub
Sub 画像を挿入して縦横比を解除してサイズ指定()
'Picture.Insertは非表示のメンバ
'Sub InsPict()推奨(たぶん)
Dim pic As Picture
Set pic = Sheet1.Pictures.Insert(ThisWorkbook.Path & "\hoge.png")
With pic
'縦横比の固定解除
.ShapeRange.LockAspectRatio = msoFalse
.Width = 700
.Height = 400
.Top = 0
.Left = 0
End With
End Sub
Sub InsPict()
Dim objFileName As String
Dim objShape As Shape
objFileName = Application.GetOpenFilename _
("Pictures (*.gif; *.jpg; *.bmp; *.tif),*.gif; *.jpg; *.bmp; *.tif", , "画像選択ダイアログ")
'アクティブセルの位置に図の幅と高さを Double型 50 ポイントに指定して画像を挿入します
'
Set objShape = ActiveSheet.Shapes.AddPicture( _
fileName:=objFileName, _
LinkToFile:=False, _
SaveWithDocument:=True, _
Left:=Selection.Left, _
Top:=Selection.Top, _
Width:=50#, _
Height:=50#)
'図のサイズを元のサイズに戻します
'!1はSingleで元のサイズに対する倍率を指定している
With objShape
.ScaleHeight 1!, msoTrue
.ScaleWidth 1!, msoTrue
End With
End Sub
Sub 別ブックのプロシージャ呼び出し()
Application.Run "Book2!Test2"
End Sub
'(2005年5月くらいのwww2.moug.net過去ログ情報から)
'印刷設定の倍率を取得
Sub try()
'自動設定{横:1,縦:無指定}
ExecuteExcel4Macro "Page.Setup(,,,,,,,,,,,,{1,#N/A})"
'zoom設定{横:無指定,縦:無指定}
ExecuteExcel4Macro "Page.Setup(,,,,,,,,,,,,{#N/A,#N/A})"
'zoom取得
MsgBox ExecuteExcel4Macro("Get.Document(62)")
End Sub
VBで変数のアドレスを取得する
VarPtr - 変数のアドレスを返します。
VarPtrArray - 配列のアドレスを返します。(excelVBA不可)
StrPtr - UNICODE の文字列バッファーのアドレスを返します。
VarPtrStringArray - 文字列の配列のアドレスを返します。(excelVBA不可)
ObjPtr - オブジェクトによって参照されるインターフェイスには、ポインターを返します変数です。
'■見えない「名前定義」の修復
Public Sub VisibleNames()
Dim Name As Name
For Each Name In Excel.Names
If Name.Visible = False Then
Name.Visible = True
End If
Next
MsgBox "すべての名前の定義を表示しました。", vbOKOnly
End Sub
Public Sub inVisibleNames()
Dim Name As Name
For Each Name In Excel.Names
If Name.Visible Then
Name.Visible = False
End If
Next
MsgBox "すべての名前の定義を非表示しました。", vbOKOnly
End Sub
'■複数セルの選択
Function usedcells() As Variant
usedcells = _
Array("B3", "B5", "B7", "B9", "B11", "B13", "B15", "B17", "B19", "B21", "B23", _
"B25", "B27", "B29", "B31", "B33", "B35", "B37", "B39", "B41", "H3", "H5", "H7", _
"H9", "H11", "H13", "H15", "H17", "H19", "H21", "H23", "H25", "H27", "H29", "H31", _
"H33", "H35", "H37", "H39", "H41", "N3", "N5", "N7", "N9", "N11", "N13", "N15", _
"N17", "N19", "N21", "N23", "N25", "N27", "N29", "N31", "N33", "N35", "N37", "N39", "N41")
End Function
Sub usedCellsSelect()
Dim i As Long
Dim rng As Range
Dim vAry As Variant
vAry = usedcells
Set rng = Range(vAry(LBound(vAry)))
For i = LBound(vAry) + 1 To UBound(vAry)
Set rng = Union(rng, Range(vAry(i)))
Next
Me.Activate
rng.Select
End Sub
'■指定した文字列キーの登場数とキーのLong値の合計を返すクラス
Option Explicit
'clsCollectionCountSum クラスモジュール
Private mclctn As Collection
Private Sub Class_Initialize()
Set mclctn = New Collection
End Sub
Public Sub Add(Value As Long, key As String)
Dim Item As Collection
Dim o As Object
On Error Resume Next
Set o = mclctn(key)
'引数が不正です:5
If Err.Number = 5 Then
Set Item = New Collection
On Error GoTo 0
End If
On Error Resume Next
mclctn.Add Item, key
'キー重複エラーのトラップ
If Err.Number = 457 Then
mclctn(key).Add Value
On Error GoTo 0
Else
Item.Add Value
End If
End Sub
Public Property Get CountIf(key As String) As Long
CountIf = mclctn(key).Count
End Property
Public Property Get SumTotal(key As String) As Long
Dim v As Variant
Dim lng As Long
For Each v In mclctn(key)
lng = lng + CLng(v)
Next
SumTotal = lng
End Property
Sub test()
Dim obj As New clsCollectionCountSum
obj.Add 1, "masao"
obj.Add 2, "masao"
obj.Add 2, "yumiko"
Debug.Print "masao", obj.CountIf("masao") & " 回登場", "合計は " & obj.SumTotal("masao")
Debug.Print "yumiko", obj.CountIf("yumiko") & " 回登場", "合計は " & obj.SumTotal("yumiko")
' masao 2 回登場 合計は 3
' yumiko 1 回登場 合計は 2
End Sub
Option Explicit
Private Function subGetFreeSpace(FolderName As String) As String()
Dim tmpPath As String
Dim sCmd As String
Dim ko As Long
Dim ff() As String
Dim fso As Object 'As New Scripting.FileSystemObject
Set fso = CreateObject("scripting.filesystemobject")
Dim ts As Object 'Scripting.TextStream
Dim tf As Object 'File
'作業用ファイル名
tmpPath = Environ$("Temp") & "\" & fso.GetTempName
Set ts = fso.CreateTextFile(Filename:=tmpPath, Unicode:=True)
ts.Close
Set tf = fso.GetFile(tmpPath)
'a:d ディレクトリ属性の表示
sCmd = "DIR """ & FolderName & """ /a:d >> """ & tmpPath & """"
Dim WSO As Object 'New WshShell
Set WSO = VBA.CreateObject("WScript.Shell")
'7:ウィンドウを最小化ウィンドウとして表示します。
'アクティブなウィンドウは切り替わりません。
Const cnsWinStyle As Integer = 7
With WSO
'第三引数は bWaitOnReturn
'実行終了まで次のステップに進むのを待つか否か
ko = .Run("CMD /U/C " & sCmd, cnsWinStyle, True)
End With
Dim io As Integer
Dim buf() As Byte
Dim flg As Boolean
io = FreeFile()
Open tmpPath For Binary As io
If LOF(io) > 0 Then
flg = True
'LOFで可変長文字列のバイト数を取得
'文字列データはバイト型の配列である
ReDim buf(1 To LOF(io))
'Getステートメントは第三引数のサイズ分のバイト数を読み込む
Get #io, , buf
End If
Close io
Kill tmpPath
'BOMの削除.1文字2バイト、バイト配列なので先頭2バイトを削除
Dim buf2() As Byte
Dim i As Long
ReDim buf2(1 To UBound(buf) - 2)
For i = 1 To UBound(buf2)
buf2(i) = buf(i + 2)
Next
If flg Then
ff() = Split(buf2, vbCrLf)
End If
subGetFreeSpace = ff()
End Function
'ドライブ名を割り当てずに空き容量を取得する
Function GetByteFreeSpace(FolderPath As String) As Double
Dim list() As String
list() = subGetFreeSpace(FolderPath)
Dim freeSpace As String
freeSpace = list(UBound(list) - 1)
freeSpace = Split(Replace(Trim$(freeSpace), String(2, ChrW(32)), "●"), "●")(1)
With CreateObject("VBScript.RegExp")
.Pattern = "\D"
.Global = True
freeSpace = .Replace(freeSpace, vbNullString)
End With
GetByteFreeSpace = CDbl(freeSpace)
End Function
Sub OnActionに引数を渡す()
Dim chkbx As Excel.CheckBox
Set chkbx = CheckBoxes.Add(1, 1, 1, 1)
Dim str As String
str = "'thisworkbook.gtest""" & chkbx.Name & """'"
Debug.Print str '⇒ 'thisworkbook.gtest"Check Box 10"'
chkbx.OnAction = str
''thisworkbook
'
'Sub gTest(str As String)
' MsgBox str
'End Sub
End Sub
Option Explicit
'閉じているブックに指定した名前のシートが含まれていればTRUE
Function IsExistWsNameInCloseBook( _
wbFullName As String, wsName As String) As Boolean
Dim v
For Each v In GetWsNames(wbFullName)
'Debug.Print v
If CStr(v) = wsName Then
IsExistWsNameInCloseBook = True
Exit For
End If
Next
End Function
'閉じているエクセルブックのシート名を取得
Function GetWsNames(wbFullName As String) As Collection
Const adSchemaTables As Long = 20
Dim adoCn As Object 'ADODB.Connection
Dim adoRs As Object 'ADODB.Recordset
Dim shName As String
Dim chk As String
Dim wsNames As New Collection
Set adoCn = CreateObject("ADODB.Connection")
adoCn.Open ("Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source=" & wbFullName & ";" & _
"Extended Properties=Excel 12.0;")
Set adoRs = adoCn.OpenSchema(adSchemaTables)
Do Until adoRs.EOF
If adoRs Is Nothing Then Exit Do
shName = adoRs.Fields("TABLE_NAME").Value
chk = Right$(shName, 1)
If chk = "$" Or chk = "'" Then
wsNames.Add Left$(shName, Len(shName) - 1)
End If
adoRs.MoveNext
Loop
adoRs.Close
Set adoRs = Nothing
adoCn.Close
Set adoCn = Nothing
Set GetWsNames = wsNames
End Function
Sub test()
Debug.Print IsExistWsNameInCloseBook("C:\Users\yama\Desktop\ブロクファイル\エラーのトラップをどこに仕掛けるか\xl.xlsm", "Index")
End Sub
Option Explicit
'方眼用紙エクセルに出会ってしまった時のツール
Private Type typHdrMem
hdrstr As Collection
lvl As Collection
rw As Collection
End Type
Private mHdrMem As typHdrMem
'選択範囲のセルを行方向単位で結合する
Sub mergeCell()
Dim rng As Range
Dim rw As Range
Set rng = Selection
For Each rw In rng.Rows
rw.Cells.Merge
Next
End Sub
'方眼用紙の階層見出し
Sub set番号階層見出し( _
rng As Range, jointChr As String, Optional preFix As String, _
Optional endChr As String)
Call delete見出し番号(rng, jointChr, endChr)
Dim clm As Range
Dim c As Range
Dim lvl As Long
Dim lvlCnt As Long
Dim hdr As String
Dim hdrPre As String
Dim hdrCnt As Long
With mHdrMem
Set .hdrstr = New Collection
Set .lvl = New Collection
Set .rw = New Collection
End With
Set rng = Selection
For Each clm In rng.Columns
If Application.CountA(clm) > 0 Then
lvl = lvl + 1
hdrCnt = 0
End If
For Each c In clm.Cells
If IsEmpty(c) = False Then
hdrCnt = hdrCnt + 1
If lvl < 2 Then
hdr = CStr(hdrCnt)
Else
hdr = getHdr(lvl - 1, c.Row)
If hdrPre <> hdr Then
hdrPre = hdr
hdrCnt = 1
End If
End If
If CBool(Len(preFix)) Then
If lvl = 1 Then
c.Value = preFix & jointChr & _
hdr & endChr & " " & c.Value
Else
c.Value = preFix & jointChr & _
hdr & jointChr & CStr(hdrCnt) & endChr & " " & c.Value
End If
Else
If lvl = 1 Then
c.Value = _
hdr & endChr & " " & c.Value
Else
c.Value = _
hdr & jointChr & CStr(hdrCnt) & endChr & " " & c.Value
End If
End If
End If
With mHdrMem
If lvl < 2 Then
.hdrstr.Add hdr
Else
.hdrstr.Add hdr & jointChr & CStr(hdrCnt)
End If
.rw.Add c.Row
.lvl.Add lvl
End With
Next
Next
End Sub
'行とlvlを指定してヘッダー文字を取り出す
Private Function getHdr(lvl As Long, rw As Long) As String
Dim str As String
Dim i As Long
With mHdrMem
For i = 1 To .rw.Count
If .rw(i) = rw And .lvl(i) = lvl Then
getHdr = CStr(.hdrstr(i))
Exit For
End If
Next
End With
End Function
Private Sub delete見出し番号( _
rng As Range, jointChr As String, Optional endChr As String)
Dim c As Range
Dim str As String
Dim ch As String
For Each c In rng.Cells
If IsEmpty(c.Value) = False Then
str = c.Value
ch = Left$(str, 1)
Do Until Not (ch = jointChr Or IsNumeric(ch) Or ch = endChr)
str = Right$(str, Len(str) - 1)
ch = Left$(str, 1)
Loop
c.Value = Trim$(str)
End If
Next
End Sub
Sub test()
Call set番号階層見出し(Selection, "-", "4", ".")
'Call set番号階層見出し(Selection, "-")
End Sub
'標準モジュール
Option Explicit
'方眼用紙エクセルに出会ってしまった時のツール2
Private Type typHdrMem
hdrstr As Collection
lvl As Collection
rw As Collection
End Type
Public Enum enmMidashi
maruSuji
AlfUpper
alfUnder
End Enum
Private mJointChr As String '1-1-① とか間を繋げる文字
Private mPreHeader As String '開始番号を指定する場合に指定"4"を指定すれば、 4-1-1 とかなる。
Private mEndChr As String '"."を指定すると、4-4-1. となる。
Private mEscapeChr As String
Private mRng As Range
Private mHdrMem As typHdrMem
'選択範囲のセルを行方向単位で結合する
Sub mergeCell()
Dim rng As Range
Dim rw As Range
Set rng = Selection
For Each rw In rng.Rows
rw.Cells.Merge
Next
End Sub
'方眼用紙の階層見出し
Sub set番号階層見出し()
Call delete見出し番号
Dim clm As Range
Dim c As Range
Dim lvl As Long
Dim lvlCnt As Long
Dim hdr As String
Dim hdrPre As String
Dim hdrCnt As Long
With mHdrMem
Set .hdrstr = New Collection
Set .lvl = New Collection
Set .rw = New Collection
End With
For Each clm In mRng.Columns
If Application.CountA(clm) > 0 Then
lvl = lvl + 1
hdrCnt = 0
End If
For Each c In clm.Cells
If IsEmpty(c) = False And Left$(c.Value, 1) <> mEscapeChr Then
hdrCnt = hdrCnt + 1
If lvl = 1 Then
hdr = CStr(hdrCnt)
Else
hdr = getHdr(lvl, c.Row)
If hdrPre <> hdr Then
hdrPre = hdr
hdrCnt = 1
End If
End If
'3階層目以降は数字の変化球
If lvl > 2 Then
Select Case lvl
Case 3
'括弧囲み数字(1)
hdr = "(" & hdrCnt & ")"
Case 4
'丸囲み数字①~⑳の20個
hdr = cnvPttnDegit(hdrCnt, 20, maruSuji)
Case 5
'大文字アルファベット26文字
hdr = cnvPttnDegit(hdrCnt, 26, AlfUpper)
Case 6
'小文字アルファベット26文字
hdr = cnvPttnDegit(hdrCnt, 26, alfUnder)
Case Else
'定義がないので・
hdr = "・"
End Select
c.Value = _
hdr & IIf(hdr = "・", "", mEndChr) & " " & c.Value
Else
If lvl = 1 Then
c.Value = IIf(CBool(Len(mPreHeader)), mPreHeader & mJointChr, "") & _
hdr & mEndChr & " " & c.Value
Else
c.Value = IIf(CBool(Len(mPreHeader)), mPreHeader & mJointChr, "") & _
hdr & mJointChr & CStr(hdrCnt) & IIf(hdr = "・", "", mEndChr) & " " & c.Value
End If
End If
End If
With mHdrMem
.hdrstr.Add hdr
.rw.Add c.Row
.lvl.Add lvl
End With
Next
Next
End Sub
'行とlvlを指定して指定レベル未満のヘッダー文字を繋げて返す
Private Function getHdr(lvl As Long, rw As Long) As String
Dim str As String
Dim i As Long
Dim lvldepth As Long
With mHdrMem
For lvldepth = 1 To lvl - 1
For i = 1 To .rw.Count
If .rw(i) = rw And .lvl(i) = lvldepth Then
If lvl = 2 Then
str = CStr(.hdrstr(i))
Exit For
Else
str = str & CStr(.hdrstr(i))
End If
End If
Next
Next
End With
getHdr = str
End Function
'数字を丸囲み数字で返すなどパターンの繰り返し文字を返す
Function cnvPttnDegit(hdrCnt As Long, ItemMax As Long, mode As enmMidashi) As String
Dim ketaval As Long
Dim ketavals As New Collection
Dim val As Long
val = hdrCnt
'開始位置の取得
Dim i As Long
Dim kijun As Long
'ItemMax:0の無い進数、iは桁数を求めている。
'10を表現するには0の無い2進数で 222(2^2*2 + 2^1*2 + 2^0*2 = 11)
'で3桁必要。
i = 0
Do
kijun = kijun + (ItemMax ^ i * ItemMax)
If val <= kijun Then
Exit Do
End If
i = i + 1
Loop
'大きい位から値を取得する
Do
ketaval = val \ ItemMax ^ i
'余りが一つ下の位の数より小さいと
'一つしたの位が0になってしまう。
'0は使えないので、余りが一つしたの位の数
'未満の場合、商から1を引く(ただし1の位を除く)
If i > 0 Then
If _
val Mod ItemMax ^ i < _
ItemMax ^ (i - 1) Then
ketaval = ketaval - 1
End If
End If
ketavals.Add ketaval
val = val - ItemMax ^ i * ketaval
i = i - 1
Loop Until i < 0
Dim v
Dim str As String
Dim flg As Boolean
For Each v In ketavals
If v > 0 Then flg = True
If flg Then
Select Case mode
Case enmMidashi.maruSuji
str = str & ChrW(AscW("①") + v - 1)
Case enmMidashi.AlfUpper
str = str & ChrW(AscW("A") + v - 1)
Case enmMidashi.alfUnder
str = str & ChrW(AscW("a") + v - 1)
End Select
End If
Next
cnvPttnDegit = str
End Function
Private Function IsTgtChr(ch As String) As Boolean
If ch = mEscapeChr Or ch = vbNullString Then
IsTgtChr = False
Exit Function
End If
If _
ch = mJointChr Or _
IsNumeric(ch) Or _
ch = mEscapeChr Or _
ch = mEndChr Or _
ch = "(" Or ch = ")" Or _
(AscW(ch) >= AscW("①") And AscW(ch) <= AscW("⑳")) Or _
(AscW(ch) >= AscW("A") And AscW(ch) <= AscW("Z")) Or _
(AscW(ch) >= AscW("a") And AscW(ch) <= AscW("z")) _
Then
IsTgtChr = True
Else
IsTgtChr = False
End If
End Function
Private Sub delete見出し番号()
Dim c As Range
Dim str As String
Dim ch As String
For Each c In mRng.Cells
If IsEmpty(c.Value) = False Then
str = c.Value
ch = Left$(str, 1)
Do Until IsTgtChr(ch) = False
str = Right$(str, Len(str) - 1)
ch = Left$(str, 1)
Loop
c.Value = Trim$(str)
End If
Next
End Sub
Sub test()
'オプション
mJointChr = "-" '1-1-① とか間を繋げる文字
mPreHeader = "" '開始番号を指定する場合に指定"4"を指定すれば、 4-1-1 とかなる。
mEndChr = "." '"."を指定すると、4-4-1. となる。
'次に指定する文字から始まる行は見出しを付けない
'空白を指定しても無視される
mEscapeChr = "_"
Set mRng = Selection
Call set番号階層見出し
End Sub
yamaV1.02β