このページに含まれるプログラム、ファイル等については、
Sub CopyAsPicture()
Dim tempBoolean As Boolean
tempBoolean = ActiveWindow.DisplayGridlines
ActiveWindow.DisplayGridlines = False
Selection.CopyPicture Appearance:=xlScreen, Format:=xlPicture
ActiveWindow.DisplayGridlines = tempBoolean
End Sub
Function Vlookup2(SA As Range, col As Integer, ParamArray cond() As Variant) As Variant
Dim a As Range, r As Range
Dim count As Integer, c As Variant, check As Boolean
For Each a In SA.Areas
For Each r In a.Rows
count = 1: check = True
For Each c In cond()
If r.Columns(count) Like c Then
count = count + 1
Else
check = False: Exit For
End If
Next c
If check Then Vlookup2 = r.Columns(col): Exit Function
Next r
Next a
Vlookup2 = 0
End Function
=VlookUp2(B2:E5,4,"7","Wed")
Function VlookArea(str As String, SA As Range, Optional col As Integer = 1) As Range
Dim temp As Range, a As Range, r As Range
Set temp = Nothing
For Each a In SA.Areas
For Each r In a.Rows
If str Like r.Columns(col).Value Then
If temp Is Nothing Then
Set temp = r
Else
Set temp = Union(temp, r)
End If
End If
Next r
Next a
Set VlookArea = temp
End Function
VlookArea("test",Range("B2:E5"),2).select
Function SumColor(rngSelect As Range, intColor As Integer) As Double
Dim a As Range, r As Range, sum As Double
sum = 0#
For Each a In rngSelect.Areas
For Each r In a.Cells
If r.Interior.ColorIndex = intColor And IsNumeric(r) = True Then sum = sum + r
Next r
Next a
SumColor = sum
End Function
=SUMCOLOR(A1:A5,3)
Function RowDoubling(Optional DoubleNum As Integer = 0, Optional Target As Range = Nothing) As Range
On Error GoTo ErrorRowDoubling
Dim i As Integer, j As Integer, RowNum As Integer, r As Range
If Target Is Nothing Then Set Target = Selection
If DoubleNum = 0 Then DoubleNum = CInt(InputBox("何倍にしますか?", , "2"))
RowNum = Target.Rows.count
If RowNum * DoubleNum > Target.Parent.Rows.count Or DoubleNum < 2 Then
Set RowDoubling = Target
Else
Application.ScreenUpdating = False
Set r = Target.Rows(1)
For i = 1 To RowNum
For j = 2 To DoubleNum
r.Copy
r.Insert Shift:=xlShiftDown
Next j
Set r = r.Offset(1, 0)
Next i
Set RowDoubling = Range(Target.Rows(1).Offset(-DoubleNum + 1, 0), r.Offset(-1, 0))
Application.CutCopyMode = False
Application.ScreenUpdating = True
End If
Exit Function
ErrorRowDoubling:
Set RowDoubling = Target
On Error GoTo 0
End Function
RowDoubling(3).select
Sub DispSpecialCell()
On Error Resume Next
Application.Dialogs(xlDialogSelectSpecial).Show
On Error GoTo 0
End Sub
Sub Kakko(Optional Target As Range = Nothing, Optional OP As String = "(", Optional CL As String = ")")
On Error GoTo KakkoError
Dim a As Range, r As Range, StdFont As Font
If Target Is Nothing Then Set Target = Selection
For Each a In Target.Areas
For Each r In a.Cells
With r.Characters(1, 1)
.Insert OP & .Text
End With
With r.Characters(r.Characters.count, 1)
.Insert .Text & CL
End With
Next r
Next a
Exit Sub
KakkoError:
r = "'" & r
Resume
End Sub
Sub 大括弧()
Kakko Selection, "[", "]"
End Sub
Sub IncLine()
Selection.Copy
Selection.Insert Shift:=xlDown
Application.CutCopyMode = False
Selection.Offset(1, 0).Select
Selection.ClearContents
End Sub
Sub MakeTextBox(Optional dummy As Integer = 0)
Dim ttop As Single, tleft As Single, theight As Single, twidth As Single
Dim nowShape As Shape
Dim nowSelection
If TypeName(Selection) = "ChartArea" Then
Set nowSelection = Selection.Parent.Parent.ShapeRange
Else
Set nowSelection = Selection
End If
With nowSelection
ttop = .Top
tleft = .Left
theight = .Height
twidth = .Width
End With
Set nowShape = ActiveSheet.Shapes.AddShape(msoShapeRectangle, tleft, ttop, twidth, theight)
With nowShape
.Fill.Visible = msoFalse
.Line.Visible = msoFalse
.Select
With .TextFrame
.MarginLeft = 0#
.MarginRight = 0#
.MarginTop = 0#
.MarginBottom = 0#
.Characters.Text = ""
End With
End With
End Sub
Sub ShapesSelectAll(Optional dummy As Integer = 0)
ActiveSheet.Shapes.SelectAll
End Sub
SOFT-Xさんのホームページを賑わせていた私のプログラムを紹介します。表の内のある項目に注目して、重複している行があれば削除するというものです。このプログラムの特徴は
'Table:チェックする表を指定します。(データ部分のみを指定しますが、通常、タイトル行はデータと重複することはないと思いますので、含まれてもかまいません。)
'ColumnNo:検査する項目の番号(表内での列の番号です。)
'Order:重複行のうちxlAscendingは一番最初の行を残し、xlDesendingは一番最後の行を残します。
Function TrimTable(Optional ByVal Table As Range = Nothing, Optional ByVal ColumnNo As Long = 1, Optional Order As XlSortOrder = xlAscending) As Range
Dim WorkRange As Range
Dim Start As Long, Max As Long, l As Long
Dim NowString As String
If Table Is Nothing Then
Set Table = Selection.CurrentRegion
ColumnNo = ActiveCell.Column - Table.Column + 2
Else
ColumnNo = ColumnNo + 1
End If
Max = Table.Rows.Count
If Max > 1 Then
Application.ScreenUpdating = False
With Table
.Cells(1).EntireColumn.Insert xlShiftToRight
Set WorkRange = .Offset(0, -1).Resize(ColumnSize:=.Columns.Count + 1)
End With
With WorkRange
.Cells(1) = 1
.Cells(1).AutoFill .Columns(1), xlFillSeries
.Sort Key1:=.Cells(1, ColumnNo), Order1:=xlAscending, Key2:=.Cells(1), Order2:=Order, Header:=xlNo, OrderCustom:=1, MatchCase:=True, Orientation:=xlSortColumns
'TrimPartStart
NowString = .Cells(1, ColumnNo).Text
Start = 2: l = 2
Do
If .Cells(l, ColumnNo).Text <> NowString Then
If Start <> l Then
Range(.Rows(l), .Rows(Max)).Copy .Cells(Start, 1)
Range(.Rows(Max - l + Start + 1), .Rows(Max)).ClearContents
Max = Max - l + Start
l = Start
End If
Start = l + 1
NowString = .Cells(l, ColumnNo).Text
End If
l = l + 1
Loop While l <= Max
If Start <> Max + 1 Then
Range(.Rows(Start), .Rows(Max)).ClearContents
Max = Max - Start + 1
End If
'TrimPartEnd
.Sort Key1:=.Cells(1), Order1:=xlAscending, Header:=xlNo, OrderCustom:=1, MatchCase:=True, Orientation:=xlSortColumns
.Cells(1).EntireColumn.Delete xlShiftToLeft
End With
Application.ScreenUpdating = True
End If
Set TrimTable = Range(Table.Rows(1), Table.Rows(Max))
End Function
Sub TrimTable2(Optional Target As Range = Nothing)
Dim temp As Range
If Target Is Nothing Then Set Target = Selection.CurrentRegion
With Target
Application.ScreenUpdating = False
Set temp = ActiveWorkbook.Worksheets.Add.Cells(1)
.AdvancedFilter Action:=xlFilterCopy, CopyToRange:=temp, Unique:=True
.Clear
temp.CurrentRegion.Copy .Cells(1)
Application.DisplayAlerts = False
temp.Worksheet.Delete
Application.DisplayAlerts = True
Application.ScreenUpdating = False
End With
End Sub
' 関数名:SaveCopy
' 引数: Path String (Optional)
' 説明: 現在使用しているファイルのバックアップファイルを作成します。
' 引数Pathで保存するフォルダを指定します。
' (フォルダが存在しない場合はエラーとなります。)
' 省略した場合は元のファイルと同じフォルダに保存します。
'
' バックアップファイルの名前は拡張子".xls"の前に".bak"をつけた
' 名前になります(それぞれ、定数XLS、DefaultBAKで定義しています)。
' ただし、フォルダを指定した場合は".bak"は付きません。
' また、一時ファイル等で拡張子".xls"が無い場合は自動で付加します。
'
' もし、その名前が既に使用されていた場合は、".bak"に2から順に
' 数字をつけたファイル名を検索し、存在しないファイル名を探して
' 保存します(フォルダを指定した場合も同様に".bak"がつきます。
' StartNumberに開始番号を定義しています。)
'
Sub SaveCopy(Optional Path As String = "")
Const XLS As String = ".xls", DefaultBAK As String = ".bak"
Const StartNumber As Integer = 2
Dim fs As Object
Dim NewFileName As String, NowPath As String, NowName As String
Dim BAK As String
Dim i As Integer
Set fs = CreateObject("Scripting.FileSystemObject")
If Path = "" Then
NowPath = ActiveWorkbook.Path: BAK = DefaultBAK
Else
NowPath = Path: BAK = ""
End If
NowName = ActiveWorkbook.Name
If InStr(1, NowName, XLS, vbTextCompare) = 0 Then
NowName = NowName & XLS
End If
NewFileName = Replace(NowName, XLS, BAK & XLS)
i = StartNumber
BAK = DefaultBAK
Do While fs.FileExists(fs.BuildPath(NowPath, NewFileName))
NewFileName = Replace(NowName, XLS, BAK & i & XLS)
i = i + 1
Loop
On Error Resume Next
ActiveWorkbook.SaveCopyAs Filename:=fs.BuildPath(NowPath, NewFileName)
If Err.Number <> 0 Then MsgBox "書き込みに失敗しました。"
Err.Clear
On Error GoTo 0
End Sub
Private Function SheetLock(Sheet As Worksheet, Optional Switch As VBA.VbTriState = vbUseDefault, Optional PassWord As String = "") As Boolean
On Error Resume Next
Static DefaultProtect As Boolean
Err.Clear
Select Case Switch
Case vbTrue
If DefaultProtect = True Then
Sheet.Protect PassWord:=PassWord
End If
SheetLock = True
Case vbFalse
DefaultProtect = Sheet.ProtectContents
If DefaultProtect = True Then Sheet.Unprotect PassWord
If Err.Number <> 0 Then
SheetLock = False
Else
SheetLock = True
End If
Case Else
SheetLock = DefaultProtect
End Select
On Error GoTo 0
End Function
Sub test()
If SheetLock(ActiveSheet, vbFalse) = True Then
Cells(1, 1) = 1
Cells(1, 2) = Cells(1, 1) + Cells(1, 2)
SheetLock ActiveSheet, vbTrue
Else
MsgBox "パスワードが解除できません。"
End If
End Sub
まず、セルのプロパティで「保護」の欄に「ロック」という項目があるのをご存知ですか?
通常はチェックが入った状態ですが、このチェックを消してシートに保護を掛けると、
シートが保護された状態で、そのセルの値を変更することができます。
そして、値を入力した後にTabキーを押すとなんと、次の保護されていないセルまで、
一気にカーソルが飛ぶんですね。非常に便利な機能です。
ただ、多分、皆さんは入力した後にリターンキーを押しますよね。するとやはり、
ロックしているセルにカーソルが移ってしまうんです。これは困ります。
そこで次のプログラムです。
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Application.EnableEvents = False
With Target.Cells(1)
If .Locked = True And _
.Worksheet.ProtectContents = True And _
Application.MoveAfterReturn = True Then
Select Case Application.MoveAfterReturnDirection
Case xlToRight: .Offset(0, -1).Next.Select
Case xlToLeft: .Offset(0, 1).Next.Select
Case xlUp: .Offset(1, 0).Next.Select
Case xlDown: .Offset(-1, 0).Next.Select
End Select
End If
End With
Application.EnableEvents = True
End Sub
行の高さや列の幅を一番大きいセルに合わせる方法をご存知ですか。
例えば、列を選択して列タイトル(例えばA)などの幅調節ができる部分で
ダブルクリックすると、選んだ全部の列について自動的に調節してくれます。
しかし、例えば表をきれいにしたいんだけど、キャプションが横長で、
それに合わせてセルを横長にしたくない。
というときには、以下のマクロが有効です。
Sub SelectedAutoFit()
Dim SA As Range
For Each SA In Selection.Areas
With SA
.Columns.AutoFit
.Rows.AutoFit
End With
Next SA
End Sub
以前、さわりだけ書いたマクロです。図形やグラフなどを一度切り取ってから、貼り付けたいセル範囲を選択した上で以下のプログラムを実行すると、そのセル範囲に合わせた大きさで図形等を貼り付けます。2番目のプログラムは図形の縦横の比率を変えずに貼り付けます。大きさの調整で困っていた方はぜひお使いください。
ちなみにNyama.xlsに収録済みです。
Sub CellSizePaste()
On Error Resume Next
Dim nowCells As Range
Dim nowShapeRange As ShapeRange
Set nowCells = Selection
ActiveSheet.Paste
If TypeName(Selection) = "ChartArea" Then
Set nowShapeRange = Selection.Parent.Parent.ShapeRange
Else
Set nowShapeRange = Selection.ShapeRange
End If
With nowShapeRange
.LockAspectRatio = msoFalse
.Height = nowCells.Height
.Width = nowCells.Width
.Top = nowCells.Top
.Left = nowCells.Left
End With
End Sub
Sub CellSizePaste2()
On Error Resume Next
Dim nowCells As Range
Dim nowShapeRange As ShapeRange
Dim mag As Double
Set nowCells = Selection
ActiveSheet.Paste
If TypeName(Selection) = "ChartArea" Then
Set nowShapeRange = Selection.Parent.Parent.ShapeRange
Else
Set nowShapeRange = Selection.ShapeRange
End If
With nowShapeRange
mag = Application.WorksheetFunction.Min(CDbl(nowCells.Height) / .Height, CDbl(nowCells.Width) / .Width)
.ScaleHeight mag, False
.ScaleWidth mag, False
.Top = nowCells.Top + (nowCells.Height - .Height) / 2
.Left = nowCells.Left + (nowCells.Width - .Width) / 2
End With
End Sub
下のような表があるとします。B2-B4は入力データ、B5は数式=SUM(B2:B4)が入ってるとします。この場合、C列にはどんな数式を書きますか?
| A | B | C | |
| 1 | No. | Value | % |
| 2 | 1 | 10 | 20 |
| 3 | 2 | 15 | 30 |
| 4 | 3 | 25 | 50 |
| 5 | Total | 50 | 100 |
Sub AbsoluteToRelative()
Dim a As Range, r As Range
If TypeName(Selection) = "Range" Then
For Each a In Selection.Areas
For Each r In a.Cells
If r.HasFormula Then
r.FormulaLocal = Replace(r.FormulaLocal, "$", "")
End If
Next r
Next a
Else
MsgBox "セルを選択してから実行してください。", vbOKOnly, "絶対座標の相対座標への変換"
End If
End Sub
別のアプリケーションからExcelに数値データを取り込む際に数値以外のものが、同じセルに取り込まれることがありますよね。具体的には、下のとおりです。
| セルのデータ | 欲しい数値 (変換後のセル) |
|---|---|
| 分子量: 233.3 | 233.3 |
| 税込み 1,233円 | 1233 |
| 12.22cm2 | 12.22 |
| 数値がない場合は無視 | 数値がない場合は無視 |
Sub getNumber()
Dim r As Range, a As Range
Dim i As Integer, j As Integer
Dim txt As String
If TypeName(Selection) <> "Range" Then Exit Sub
For Each a In Selection.Areas
For Each r In a.Cells
txt = r.Text
For i = 1 To Len(txt)
If IsNumeric(Mid(txt, i, 1)) Then
txt = Right(txt, Len(txt) - i + 1)
For j = Len(txt) To 1 Step -1
If IsNumeric(Left(txt, j)) Then
r = CDbl(Left(txt, j))
Exit For
End If
Next j
Exit For
End If
Next i
Next r
Next a
End Sub
フロッピーディスク上のワークブックを直接読み込んで編集すると、(1)セーブのたびに待たされる、(2)Excelのハングアップする可能性が高くなる(と思われる)、という問題があるので、
Private Sub Workbook_Open()
FloppyDataModule.init_FloppyData '初期化の呼び出し
End Sub
---標準モジュール(FloppyDataModuleとしてください)内---
Public X As New FloppyDataClass 'アプリケーションフック
Public Sub init_FloppyData()
Set X.App = Excel.Application
X.init
End Sub
---クラスモジュール(FloppyDataClassとしてください)内---
Public WithEvents App As Application
Private Const FloppyLetter As String = "A:"
Private Const FullNameColumn As Integer = 1
Private Const NameColumn As Integer = 2
Private Const TempColumn As Integer = 3
Private index As Integer
Private ListSheet As Worksheet
Private fs As Object
Public Sub init() '初期化
index = 0
Set ListSheet = ThisWorkbook.Worksheets(1)
Set fs = CreateObject("Scripting.FileSystemObject")
End Sub
Private Sub App_WorkbookBeforeClose(ByVal Wb As Workbook, Cancel As Boolean)
Dim fileindex As Integer
If index = 0 Then '一時保存ファイルが存在しない場合
Cancel = False 'ファイルを閉じる。
Exit Sub '処理を終了する。
End If
On Error Resume Next
Err.Clear
'一時保存ファイルと一致するかどうか確認。
fileindex = Application.WorksheetFunction.Match(Wb.Name, _
Range(ListSheet.Cells(1, NameColumn), ListSheet.Cells(index, NameColumn)), 0)
If Err.Number <> 0 Then '一致しない場合
Cancel = False 'ファイルを閉じる。
Exit Sub '処理を終了する。
End If
On Error GoTo 0
'一時保存ファイルを元のファイルに上書き
'一時保存ファイルからリネームして編集した場合、
'リネーム以前のファイルの編集が反映される。
On Error Resume Next
fs.DeleteFile ListSheet.Cells(fileindex, FullNameColumn), True
On Error GoTo 0
Wb.SaveAs ListSheet.Cells(fileindex, FullNameColumn)
'一時保存ファイルを削除
' On Error Resume Next
' fs.DeleteFile ListSheet.Cells(fileindex, TempColumn), True
' On Error GoTo 0
'リストからファイル名等を削除
ListSheet.Cells(fileindex, FullNameColumn) = ""
ListSheet.Cells(fileindex, NameColumn) = ""
ListSheet.Cells(fileindex, TempColumn) = ""
End Sub
Private Sub App_WorkbookOpen(ByVal Wb As Workbook)
If (Left(Wb.Path, 2) = FloppyLetter) Then 'フロッピーであることの確認
'indexを1増加し、リストにファイル名等を入力
index = index + 1
ListSheet.Cells(index, FullNameColumn) = Wb.FullName
ListSheet.Cells(index, NameColumn) = Wb.Name
ListSheet.Cells(index, TempColumn) = fs.getSpecialFolder(2) & "\" & Wb.Name
'一時保存ファイルを作成し、そのファイルを編集するようにする。
'一時保存ファイルと同名のファイルがある場合、削除する。
On Error Resume Next
fs.DeleteFile ListSheet.Cells(index, TempColumn), True
On Error GoTo 0
Wb.SaveAs ListSheet.Cells(index, TempColumn)
End If
End Sub
Public WithEvents App As Applicationという特別な変数を作り、これに
Set X.App = Excel.Applicationでアプリケーションへの参照をセットしてやります。これにより、アプリケーションでイベントが起きるたびにクラスが呼び出され、対応する関数を(あれば)実行するようになります。今回は、ワークブックを開いたときと閉じる前に呼び出されて処理を行うことになります。
数式で得られた数値をそのまま固定値としてセルに代入します。
Sub ConstValue(Optional dummy As Integer = 0)
On Error Resume Next
Selection.Copy
Selection.PasteSpecial Paste:=xlValues, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=False
Application.CutCopyMode = False
End Sub
エクセルで計算したデータをカンマ区切りのテキストファイル(CSV)にして他のプログラムで利用する必要がよく生じます。通常の「名前を付けて保存」では以降の編集ファイルもCSVファイルに変わってしまい不便です。そこで、表示しているワークシートをCSVファイルとして書き出すマクロを作りました。
Sub WriteOutToCSV()
Dim file As Variant
Dim NewBook As Workbook
Dim NowSheet As Worksheet
Set NowSheet = ActiveSheet
file = Application.GetSaveAsFilename(ActiveSheet.Name & ".csv", "カンマ区切り形式 (*.csv), *.csv")
If file = False Then Exit Sub
Set NewBook = Workbooks.Add
NowSheet.Copy before:=NewBook.Worksheets(1)
On Error Resume Next
NewBook.Worksheets(1).SaveAs Filename:=file, FileFormat:=xlCSV
On Error GoTo 0
Application.DisplayAlerts = False
NewBook.Close
Application.DisplayAlerts = True
NowSheet.Activate
End Sub
無断転載を禁じます。