Option Explicit
Private lastrow As Long
Private maxcol As Long
Private maxrow As Long
Private saverow As Long
Private sortedFlag As Boolean
Private gmakedFlag As Boolean
Const baseSheetName As String = "成績表"
Const workSheetName As String = "作業"
Const No_koutei As Long = 19 '工程数
Const X_ratio As Double = 1# 'グラフ横軸倍率
Const Y_ratio As Double = 1# 'グラフ縦軸倍率
Const Y_unit As Long = 5 'グラフ縦軸目盛単位
Private Sub UserForm_Initialize()
Dim i As Long
Call CopyData
For i = 3 To maxrow
名前リスト.AddItem Cells(i, 1)
Next i
End Sub
Private Sub 名前リスト_Click()
Dim i As Long
Dim j As Long
Dim row As Long
Dim col As Long
Dim no As Long
Call CopyData
no = 名前リスト.ListIndex
row = no + 3
'選択した氏名と成績をコピー
Range(Cells(saverow, 1), Cells(saverow, maxcol)).Value = Range(Cells(row, 1), Cells(row, maxcol)).Value
'順位を設定(1期~4期)
For i = 1 To 4
For j = 1 To No_koutei
col = GetCol2(i, j)
If Cells(saverow, col).Value <> "" Then
Cells(saverow + 1, col).Value = WorksheetFunction.Rank(Cells(saverow, col).Value, Range(Cells(3, col), Cells(maxrow, col)), 0)
End If
Next
Next
'選択された氏名の背景色を設定(1期~4期)
For i = 1 To 4
col = GetCol1(i)
Range(Cells(row, col), Cells(row, col + No_koutei)).Interior.Color = 15773696
Next
lastrow = row
End Sub
'並べ替えボタンクリック
Private Sub btnsort_Click()
Dim i As Long
Dim j As Long
Dim col As Long
If sortedFlag = True Then
MsgBox ("既に並べ替え済み")
Exit Sub
End If
If lastrow = 0 Then
MsgBox ("名前を選択して下さい")
Exit Sub
End If
'1期~4期まで繰り返す
For i = 1 To 4
For j = 1 To No_koutei
col = GetCol2(i, j)
Range(Cells(3, col), Cells(maxrow, col)).Sort key1:=Cells(3, col), order1:=xlDescending
Next
Next
sortedFlag = True
End Sub
'期(i=1~4)を与えて、そのカラム位置(氏名のカラム位置)を返す
Private Function GetCol1(ByVal i As Long) As Long
GetCol1 = (i - 1) * (No_koutei + 2) + 1
End Function
'期(i=1~4)と工程(j=1~19)を与えて、そのカラム位置を返す
Private Function GetCol2(ByVal i As Long, ByVal j As Long) As Long
GetCol2 = (i - 1) * (No_koutei + 2) + j + 1
End Function
'期(i=1~4)を与えて、その期にデータがあるか否かを返す(true:有 false:無)
Private Function HasData(ByVal i As Long) As Boolean
Dim col As Long
Dim rg As Range
col = GetCol1(i)
HasData = False
For Each rg In Range(Cells(3, col + 1), Cells(maxrow, col + No_koutei))
If rg.Value <> "" Then
HasData = True
Exit For
End If
Next
End Function
'元データを作業シートへコピー
Private Sub CopyData()
Dim i As Long
Dim rg As String
Dim end_colstr As String
maxcol = (No_koutei + 1) * 4 + 3
end_colstr = ConvertToLetter(maxcol)
maxrow = Worksheets(baseSheetName).Cells(Rows.Count, 1).End(xlUp).row
'前回表示された内容を全てクリア
Worksheets(workSheetName).Cells.Clear
rg = "A1:" & end_colstr & maxrow
'表の全領域をコピー(A1~CEx)(x=A列の最大行)
Worksheets(baseSheetName).Range(rg).Copy Worksheets(workSheetName).Range(rg)
'作業シートをアクティベイト
Worksheets(workSheetName).Activate
'グラフを削除
Worksheets(workSheetName).Cells(1, 1).Select
If ActiveSheet.ChartObjects.Count > 0 Then
ActiveSheet.ChartObjects.Delete
End If
'フラグ及び変数の初期化
lastrow = 0
sortedFlag = False
gmakedFlag = False
saverow = maxrow + 2
End Sub
'グラフボタンクリック
Private Sub BtnGraph_Click()
Dim left As Double
Dim top As Double
Dim width As Double
Dim height As Double
Dim col As Long
Dim i As Long
If gmakedFlag = True Then
MsgBox ("既に作成済み")
Exit Sub
End If
If lastrow = 0 Then
MsgBox ("名前を選択して下さい")
Exit Sub
End If
'左位置設定(=B列の開始位置)
left = ActiveSheet.Range("A1").width
'上位置設定(=A列最大行+5行目)
top = ActiveSheet.Range("A1:A" & maxrow + 4).height
'高さ
height = 300 * Y_ratio
'幅
width = ActiveSheet.Range("B2").width * No_koutei * X_ratio
'空のグラフ作成
With ActiveSheet.ChartObjects.Add(left, top, width, height).Chart
End With
'作成したグラフのアクティベイト
ActiveSheet.ChartObjects(1).Activate
'1期から4期まで作成
For i = 1 To 4
'該当期のデータが全て空なら終了する
If HasData(i) = False Then Exit For
'新しくデータ系列を作成
ActiveChart.SeriesCollection.NewSeries
'グラフの種類・データの範囲・凡例の使用を指定
With ActiveChart.SeriesCollection(i)
'グラフの種類を設定 折れ線グラフ
.ChartType = xlLineMarkers
'X軸の項目軸を指定
.XValues = Range(Cells(2, 2), Cells(2, No_koutei + 1))
'データの指定
col = GetCol1(i)
.Values = Range(Cells(saverow + 1, col + 1), Cells(saverow + 1, col + No_koutei))
'凡例の指定
.Name = i & "期順位"
End With
Next
'スケール情報設定
ActiveChart.Axes(xlValue, xlPrimary).MinimumScale = 1
ActiveChart.Axes(xlValue, xlPrimary).MajorUnit = Y_unit
ActiveChart.Axes(xlValue, xlPrimary).MaximumScale = GetMaxScale(maxrow - 2, Y_unit)
ActiveChart.Axes(xlValue, xlPrimary).ReversePlotOrder = True
'タイトル設定
With ActiveChart
.HasTitle = True
.ChartTitle.Text = Cells(saverow, 1).Value 'グラフ対象者の氏名
End With
gmakedFlag = True
End Sub
'列番号を英文字に変換
Function ConvertToLetter(ByVal iCol As Integer) As String
Dim iAlpha As Integer
Dim iRemainder As Integer
iAlpha = Int((iCol - 1) / 26)
iRemainder = iCol - (iAlpha * 26)
If iAlpha > 0 Then
ConvertToLetter = Chr(iAlpha + 64)
End If
If iRemainder > 0 Then
ConvertToLetter = ConvertToLetter & Chr(iRemainder + 64)
End If
End Function
'人数とメモリ単位を与えてスケールの最大値を計算する
Private Function GetMaxScale(no_person, unit)
Dim i As Long
i = 0
Do While True
GetMaxScale = i * unit + 1
If GetMaxScale >= no_person Then Exit Do
i = i + 1
Loop
End Function