[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『Excel64ビット変更後のVBAコンパイルエラー』(マツ)
Office365バージョンアップ(64ビット)に伴い32ビットで作成したVBAでコンパイルエラー(型が一致しません)が発生します。詳しい方ご教示願います。
************************************************** ' 機能 :取込処理(対象フォルダにExcelファイルがあればリストアップする)
' 引数 :指定されたディレクトリ(String)
' 戻値 :なし
' **************************************************
Public Sub GetFiles(instrDir As String)
On Error GoTo Err_GetFiles
' 引数のフォルダ以下のファイル名を返す
Dim i As LongPtr ' ループカウンタ
Dim j As LongPtr ' ループカウンタ
Dim aryDir() As String ' ディレクトリ群
Dim aryFile() As String ' ファイル群
Dim strName As String ' ファイル名
Dim aryRet() As String ' 戻り値用配列
Dim intCount As Integer ' 取得件数
Dim swap As String ' 並べ替え用
Err.Clear ' エラーを初期化
ErrMSG = ""
intCount = 0
i = 0
ReDim aryDir(i)
aryDir(i) = instrDir ' フォルダをここで指定
' まず指定フォルダ以下の全サブフォルダを取得して配列aryDirへ
Do
' 最後の「\」が無ければ付与
If Right(aryDir(i), 1) <> "\" Then
strName = Dir(aryDir(i) & "\", vbDirectory)
End If
Do While strName <> ""
If GetAttr(aryDir(i) & "\" & strName) And vbDirectory Then
If strName <> "." And strName <> ".." Then
ReDim Preserve aryDir(UBound(aryDir) + 1)
aryDir(UBound(aryDir)) = aryDir(i) & "\" & strName
End If
End If
strName = Dir()
Loop
i = i + 1
If i > UBound(aryDir) Then
Exit Do
End If
Loop
' 配列aryDirの全フォルダについてファイルを取得し、配列aryFileへ
ReDim aryFile(0)
For i = 0 To UBound(aryDir)
strName = Dir(aryDir(i) & "\", vbNormal)
' strName = Dir(aryDir(i) & "\", vbNormal + vbHidden + vbReadOnly + vbSystem)
Do While strName <> ""
If Left(strName, 2) <> "~$" Then
If aryFile(0) <> "" Then
ReDim Preserve aryFile(UBound(aryFile) + 1)
End If
'2015/09/04 対象ファイルが存在しない時の不具合対応 ------------------->
'If (Right(strName, 3) = "xls" Or Right(strName, 4) = "xlsx") Then
If (LCase(Right(strName, 3)) = "xls" Or LCase(Right(strName, 4)) = "xlsx") Then
'2015/09/04 対象ファイルが存在しない時の不具合対応 ------------------->
' 戻り値用の配列に入れる
ReDim Preserve aryRet(intCount)
aryRet(intCount) = aryDir(i) & "\" & strName
intCount = intCount + 1
End If
End If
strName = Dir()
Loop
Next
'2015/09/04 対象ファイルが存在しない時の不具合対応 ------------------->
' If UBound(aryDir) > 0 Then
' ' 配列(ファイル名)をソートする
' For i = 0 To UBound(aryDir) ''ソート開始
' For j = UBound(aryDir) To i Step -1
' If aryRet(i) > aryRet(j) Then
' swap = aryRet(i)
' aryRet(i) = aryRet(j)
' aryRet(j) = swap
' End If
' Next j
' Next i
' End If
'ファイルが存在する場合
If intCount > 0 Then
' 配列(ファイル名)をソートする
For i = 0 To UBound(aryRet) ''ソート開始
For j = UBound(aryRet) To i Step -1
If aryRet(i) > aryRet(j) Then
swap = aryRet(i)
aryRet(i) = aryRet(j)
aryRet(j) = swap
End If
Next j
Next i
End If
'2015/09/04 対象ファイルが存在しない時の不具合対応 ------------------->
' 0件時
If Sgn(aryRet) = 0 Then
' InFileName = aryRet
InFileCount = 0
Exit Sub
Else
' 配列をセットして終了
InFileName = aryRet
' InFileCount = intCount - 1
InFileCount = intCount
Exit Sub
End If
Err_GetFiles:
ErrMSG = CStr(Err.Number) & ":" & Error
End Sub
< 使用 Excel:Office365、使用 OS:Windows10 >
>VBAでコンパイルエラー(型が一致しません) どの部分でエラーになるか記述しないと回答が付かないのでは。 (VAB) 2020/11/26(木) 19:39
Dim i As LongPtr ' ループカウンタ
Dim j As LongPtr ' ループカウンタ
なぜLongにしていないのか気になります。
もし上限を超えるファイル数を想定しているなら、他の変数の型も変えないといけないはず。
(通りすがりの) 2020/11/27(金) 09:32
>なぜLongにしていないのか気になります。 Microsoft ドキュメントの中に 『LongPtr は、32 ビット環境では Long に変換され、64 ビット環境では LongLong に変換されるので、実際のデータ型ではありません。 LongPtr を使用すると、32 ビット環境と 64 ビット環境の両方で実行できる 移植性のあるコードを作成できます。 ポインターおよびハンドラーには LongPtr を使用してください。』 という記事があります。 (tori) 2020/11/27(金) 11:07
' 引数のフォルダ以下のファイル名を返す
Dim i As LongPtr ' ループカウンタ
Dim j As LongPtr ' ループカウンタ
Dim aryDir() As String ' ディレクトリ群
Dim aryFile() As String ' ファイル群
Dim strName As String ' ファイル名
Dim aryRet() As String ' 戻り値用配列
Dim intCount As Integer ' 取得件数
Dim swap As String ' 並べ替え用
Err.Clear ' エラーを初期化
ErrMSG = ""
intCount = 0
i = 0
ReDim aryDir(i)←この箇所でコンパイルエラーが発生する。
aryDir(i) = instrDir ' フォルダをここで指定
' まず指定フォルダ以下の全サブフォルダを取得して配列aryDirへ
Do
' 最後の「\」が無ければ付与
If Right(aryDir(i), 1) <> "\" Then
strName = Dir(aryDir(i) & "\", vbDirectory)
End If
Do While strName <> ""
If GetAttr(aryDir(i) & "\" & strName) And vbDirectory Then
If strName <> "." And strName <> ".." Then
ReDim Preserve aryDir(UBound(aryDir) + 1)
aryDir(UBound(aryDir)) = aryDir(i) & "\" & strName
End If
End If
strName = Dir()
Loop
i = i + 1
If i > UBound(aryDir) Then
Exit Do
End If
Loop
' 配列aryDirの全フォルダについてファイルを取得し、配列aryFileへ
ReDim aryFile(0)
For i = 0 To UBound(aryDir)
strName = Dir(aryDir(i) & "\", vbNormal)
' strName = Dir(aryDir(i) & "\", vbNormal + vbHidden + vbReadOnly + vbSystem)
Do While strName <> ""
If Left(strName, 2) <> "~$" Then
If aryFile(0) <> "" Then
ReDim Preserve aryFile(UBound(aryFile) + 1)
End If
対象ファイルが存在しない時の不具合対応 ------------------->
'If (Right(strName, 3) = "xls" Or Right(strName, 4) = "xlsx") Then
If (LCase(Right(strName, 3)) = "xls" Or LCase(Right(strName, 4)) = "xlsx") Then
'対象ファイルが存在しない時の不具合対応 ------------------->
' 戻り値用の配列に入れる
ReDim Preserve aryRet(intCount)
aryRet(intCount) = aryDir(i) & "\" & strName
intCount = intCount + 1
End If
End If
strName = Dir()
Loop
Next
'対象ファイルが存在しない時の不具合対応 ------------------->
' If UBound(aryDir) > 0 Then
' ' 配列(ファイル名)をソートする
' For i = 0 To UBound(aryDir) ''ソート開始
' For j = UBound(aryDir) To i Step -1
' If aryRet(i) > aryRet(j) Then
' swap = aryRet(i)
' aryRet(i) = aryRet(j)
' aryRet(j) = swap
' End If
' Next j
' Next i
' End If
'ファイルが存在する場合
If intCount > 0 Then
' 配列(ファイル名)をソートする
For i = 0 To UBound(aryRet) ''ソート開始
For j = UBound(aryRet) To i Step -1
If aryRet(i) > aryRet(j) Then
swap = aryRet(i)
aryRet(i) = aryRet(j)
aryRet(j) = swap
End If
Next j
Next i
End If
'対象ファイルが存在しない時の不具合対応 ------------------->
' 0件時
If Sgn(aryRet) = 0 Then
' InFileName = aryRet
InFileCount = 0
Exit Sub
Else
' 配列をセットして終了
InFileName = aryRet
' InFileCount = intCount - 1
InFileCount = intCount
Exit Sub
End If
Err_GetFiles:
ErrMSG = CStr(Err.Number) & ":" & Error
End Sub
(マツ) 2020/11/27(金) 11:52
なお、Option Explicitを使った方がよいですよ。
未宣言の変数がいくつかあります。バグの元です。
VBEのオプション設定により、(今後作成するモジュールに対して)、
Option Explicitを自動挿入させることができます。
(γ) 2020/11/27(金) 13:10
考えようによっては、膨大なファイル数を想定しておりLongでは容量が足りないからLongPtrを使ったとも読み取れます。
つまりLongPtrをLongにすれば良のか、それともコード全体をLongLongに耐えられるように直さないといけない話なのか。という要件の確認です。
この様子だと、そこまで明確な要件は決まっていない雰囲気なので、
Dim i As LongPtr ' ループカウンタ
Dim j As LongPtr ' ループカウンタ
を
Dim i As Long
Dim j As Long
に変えるので十分だと思います。
APIの64bit対応で、気軽にLongをLongPtrに変えたのが原因でハマってしまった。と見受けられます。
(通りすがりの) 2020/11/27(金) 14:48
Dim i As LongPtr→Dim i As Long ' ループカウンタ
Dim j As LongPtr→Dim j As Long ' ループカウンタ
に戻して実行するとエラーメッセージが表示します。
Option Explicit
' ***** API *****(Windowsのワークフォルダ取得用)
Private Declare PtrSafe Function SHGetPathFromIDList Lib "shell32.dll" Alias "SHGetPathFromIDListA" _
(ByVal pidl As LongPtr, ByVal pszPath As String) As LongPtr
Private Declare PtrSafe Function SHBrowseForFolder Lib "shell32.dll" Alias "SHBrowseForFolderA" _
(lpBrowseInfo As BROWSEINFO) As LongPtr
Private Declare PtrSafe Function GetDesktopWindow Lib "user32" () As LongPtr
Private Declare PtrSafe Function GetTempPath Lib "kernel32" Alias "GetTempPathA" _
(ByVal nBufferLength As LongPtr, ByVal lpBuffer As String) As LongPtr
Private Const MAX_PATH As Integer = 260
Public Sub GetFiles(instrDir As String)
On Error GoTo Err_GetFiles
' 引数のフォルダ以下のファイル名を返す
Dim i As Long ' ループカウンタ
Dim j As Long ' ループカウンタ
Dim aryDir() As String ' ディレクトリ群
Dim aryFile() As String ' ファイル群
Dim strName As String ' ファイル名
Dim aryRet() As String ' 戻り値用配列
Dim intCount As Integer ' 取得件数
Dim swap As String ' 並べ替え用
Err.Clear ' エラーを初期化
ErrMSG = ""
intCount = 0
i = 0
ReDim aryDir(i)←この箇所でコンパイルエラーが発生する。
aryDir(i) = instrDir ' フォルダをここで指定
' まず指定フォルダ以下の全サブフォルダを取得して配列aryDirへ
Do
' 最後の「\」が無ければ付与
If Right(aryDir(i), 1) <> "\" Then
strName = Dir(aryDir(i) & "\", vbDirectory)
End If
Do While strName <> ""
If GetAttr(aryDir(i) & "\" & strName) And vbDirectory Then
If strName <> "." And strName <> ".." Then
ReDim Preserve aryDir(UBound(aryDir) + 1)
aryDir(UBound(aryDir)) = aryDir(i) & "\" & strName
End If
End If
strName = Dir()
Loop
i = i + 1
If i > UBound(aryDir) Then
Exit Do
End If
Loop
' 配列aryDirの全フォルダについてファイルを取得し、配列aryFileへ
ReDim aryFile(0)
For i = 0 To UBound(aryDir)
strName = Dir(aryDir(i) & "\", vbNormal)
' strName = Dir(aryDir(i) & "\", vbNormal + vbHidden + vbReadOnly + vbSystem)
Do While strName <> ""
If Left(strName, 2) <> "~$" Then
If aryFile(0) <> "" Then
ReDim Preserve aryFile(UBound(aryFile) + 1)
End If
対象ファイルが存在しない時の不具合対応 ------------------->
'If (Right(strName, 3) = "xls" Or Right(strName, 4) = "xlsx") Then
If (LCase(Right(strName, 3)) = "xls" Or LCase(Right(strName, 4)) = "xlsx") Then
'対象ファイルが存在しない時の不具合対応 ------------------->
' 戻り値用の配列に入れる
ReDim Preserve aryRet(intCount)
aryRet(intCount) = aryDir(i) & "\" & strName
intCount = intCount + 1
End If
End If
strName = Dir()
Loop
Next
'対象ファイルが存在しない時の不具合対応 ------------------->
' If UBound(aryDir) > 0 Then
' ' 配列(ファイル名)をソートする
' For i = 0 To UBound(aryDir) ''ソート開始
' For j = UBound(aryDir) To i Step -1
' If aryRet(i) > aryRet(j) Then
' swap = aryRet(i)
' aryRet(i) = aryRet(j)
' aryRet(j) = swap
' End If
' Next j
' Next i
' End If
'ファイルが存在する場合
If intCount > 0 Then
' 配列(ファイル名)をソートする
For i = 0 To UBound(aryRet) ''ソート開始
For j = UBound(aryRet) To i Step -1
If aryRet(i) > aryRet(j) Then
swap = aryRet(i)
aryRet(i) = aryRet(j)
aryRet(j) = swap
End If
Next j
Next i
End If
'対象ファイルが存在しない時の不具合対応 ------------------->
' 0件時
If Sgn(aryRet) = 0 Then
' InFileName = aryRet
InFileCount = 0
Exit Sub
Else
' 配列をセットして終了
InFileName = aryRet
' InFileCount = intCount - 1
InFileCount = intCount
Exit Sub
End If
Err_GetFiles:
ErrMSG = CStr(Err.Number) & ":" & Error
End Sub
(マツ) 2020/11/27(金) 16:40
(通りすがりの) 2020/11/27(金) 16:50
Option Explicit
' **************************************************
' 概要 :指定フォルダ以下のExcelファイルを
' 対象に集計を行う
' **************************************************
' ***** API *****(Windowsのワークフォルダ取得用)
Private Declare PtrSafe Function SHGetPathFromIDList Lib "shell32.dll" Alias "SHGetPathFromIDListA" _
(ByVal pidl As LongPtr, ByVal pszPath As String) As LongPtr
Private Declare PtrSafe Function SHBrowseForFolder Lib "shell32.dll" Alias "SHBrowseForFolderA" _
(lpBrowseInfo As BROWSEINFO) As LongPtr
Private Declare PtrSafe Function GetDesktopWindow Lib "user32" () As LongPtr
Private Declare PtrSafe Function GetTempPath Lib "kernel32" Alias "GetTempPathA" _
(ByVal nBufferLength As LongPtr, ByVal lpBuffer As String) As LongPtr
Private Const MAX_PATH As Integer = 260
' パブリック変数
Public InFileName() As String ' 画面から引き継いだフォルダ情報
Public skipFlg As Boolean ' 出力があるか?
' ■■■入力/出力フォーマット変更時はここを変えてください■■■
' 入力フォーマット
Private Const IN_BADNO As String = "A7" '
Private Const IN_ISSUE_DATE As String = "F7" '
Private Const IN_ORDER As String = "L7" '
Private Const IN_ORDER_SOURCE As String = "A9" '
Private Const IN_SUBJECT As String = "L9" '
Private Const IN_MODELS As String = "AB9" '
Private Const IN_DECENES As String = "AH9" '
' 不良発見工程はピンポイントで設定 ■
'''''''''' 1行目
Private Const IN_PROD_OUT As String = "W4" '
Private Const IN_PRO_IN As String = "AC4" '
Private Const IN_UNIT As String = "AI4" '
'''''''''' 2行目
Private Const IN_BORD_INSP As String = "W5" '
Private Const IN_MARKING_CONF As String = "AC5" '
Private Const IN_HD_TEST As String = "AI5" '
'''''''''' 3行目
Private Const IN_SYSTEM_TEST As String = "W6" '
Private Const IN_SHIPPING_INSP As String = "AC6" '
Private Const IN_FIELD_TEST As String = "AI6" '
' 入力明細行
Private Const IN_NO As String = "A" '
Private Const IN_SPOILAGE As String = "B" '
Private Const IN_BURDEN As String = "D" '
Private Const IN_PHENOMENON As String = "B" '
Private Const IN_NUM_DEFECTS As String = "D" '
Private Const IN_PRODUCT As String = "G" '
Private Const IN_TROUBLE_CONTENT As String = "P" '
Private Const IN_DEADLINE As String = "AJ" '
Private Const IN_COR_NECECE As String = "AM" '
Private Const IN_TREATMENT As String = "AP" '
Private Const IN_TREATMENT_DAY As String = "BA" '
Private Const IN_RELAP_PREVENT As String = "BD" '
Private Const IN_TC_RESULT As String = "BO" '
Private Const IN_DATE_CONFIR As String = "BX" '
Private Const IN_CONFIR_PERSON As String = "CA" '
Private Const IN_TREATMENT_SECTION As String = "AY3" '
' その他定数
Public Const DEF_FILENAME As String = _
"データ集計結果_%1%.xlsx" '
Private Const MB_OK = &H0 '
Private Const MB_TOPMOST = &H40000 '
Private Const GWL_STYLE = (-16) '
Private Const WS_SYSMENU = &H80000 '
Private Const SEP As String = "/" '
Private Const TARGET_SHEET As String = "フォーマット" '
Private Const OUT_SHEET_NAME As String = "sheet1" '
Private Const NEW_SHEET As Integer = 1 '
Private Const COL_CHAR As String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
' メッセージ定数(タイトル)
Public Const T01 As String = "データ集計ツール" ' メッセージボックスタイトル
Public Const T02 As String = "保存先の指定" ' 保存ダイアログタイトル
Public Const T03 As String = "終了します" ' 終了ダイアログタイトル
' メッセージ定数(メッセージ)
Public Const I01 As String = "集計を実行しますか?"
Public Const I03 As String = "集計処理が終了しました。" & vbCrLf & "集計結果を表示し処理を終了します。"
' メッセージ定数(エラー)
Public Const E01 As String = "指定されたフォルダが存在しません。"
Public Const E02 As String = "ファイルがオープンできません。"
Public Const E03 As String = "例外が発生しました" & vbCrLf & vbCrLf
Public Const E04 As String = "対象のファイルが存在しません。"←このエラーメッセージが表示します。
' ブラウザインフォ構造体(ダイアログ指定で使用)
Public Type BROWSEINFO
hOwner As LongPtr
pidlRoot As LongPtr
pszDisplayName As String
lpszTitle As String
ulFlags As LongPtr
lpfn As LongPtr
lParam As LongPtr
iImage As LongPtr
End Type
'''''''''''''''''''''''''''''''''''''''''''''''''''''' ここからプロパティ
' プロパティ変数
Private pInFileCount As Integer ' 入力ファイル数プロパティ(フォーム→コモン)
Private pErrMSG As String ' エラーメッセージプロパティ(コモン→フォーム)
' **************************************************
' 機能 :入力ファイル数プロパティ
' ' **************************************************
Public Property Let InFileCount(ByRef In_InFileCount As Integer)
pInFileCount = In_InFileCount
End Property
Public Property Get InFileCount() As Integer
InFileCount = pInFileCount
End Property
' **************************************************
' 機能 :エラーメッセージプロパティ
' ' **************************************************
Public Property Let ErrMSG(ByRef In_ErrMSG As String)
pErrMSG = In_ErrMSG
End Property
Public Property Get ErrMSG() As String
ErrMSG = pErrMSG
End Property
'''''''''''''''''''''''''''''''''''''''''''''''''''''' ここからイベント
' **************************************************
' 機能 :フォルダの選択ボタン押下後処理
' ' **************************************************
Public Function GetFolder(Optional Msg As String) As String
On Error GoTo Err_GetFolder
Dim bInfo As BROWSEINFO, pPath As String
Dim R As LongPtr, X As LongPtr, pos As Integer
Err.Clear ' エラーを初期化
bInfo.pidlRoot = 0&
If IsMissing(Msg) Then
bInfo.lpszTitle = "取込フォルダの選択"
Else
bInfo.lpszTitle = Msg
End If
bInfo.ulFlags = &H1
X = SHBrowseForFolder(bInfo)
pPath = Space$(512)
R = SHGetPathFromIDList(ByVal X, ByVal pPath)
If R Then
pos = InStr(pPath, Chr$(0))
GetFolder = Left(pPath, pos - 1)
Else
GetFolder = ""
End If
Exit Function
Err_GetFolder:
ErrMSG = CStr(Err.Number) & ":" & Error
End Function
'''''''''''''''''''''''''''''''''''''''''''''''''''''' ここからメイン処理
' **************************************************
' 機能 :?@取込処理(対象フォルダにExcelファイルがあればリストアップする)
' ' 引数 :指定されたディレクトリ(String)
' 戻値 :なし
' **************************************************
Public Sub GetFiles(instrDir As String)
On Error GoTo Err_GetFiles
' 引数のフォルダ以下のファイル名を返す
Dim i As Long ' ループカウンタ
Dim j As Long ' ループカウンタ
Dim aryDir() As String ' ディレクトリ群
Dim aryFile() As String ' ファイル群
Dim strName As String ' ファイル名
Dim aryRet() As String ' 戻り値用配列
Dim intCount As Integer ' 取得件数
Dim swap As String ' 並べ替え用
Err.Clear ' エラーを初期化
ErrMSG = ""
intCount = 0
i = 0
ReDim aryDir(i)
aryDir(i) = instrDir ' フォルダをここで指定
' まず指定フォルダ以下の全サブフォルダを取得して配列aryDirへ
Do
' 最後の「\」が無ければ付与
If Right(aryDir(i), 1) <> "\" Then
strName = Dir(aryDir(i) & "\", vbDirectory)
End If
Do While strName <> ""
If GetAttr(aryDir(i) & "\" & strName) And vbDirectory Then
If strName <> "." And strName <> ".." Then
ReDim Preserve aryDir(UBound(aryDir) + 1)
aryDir(UBound(aryDir)) = aryDir(i) & "\" & strName
End If
End If
strName = Dir()
Loop
i = i + 1
If i > UBound(aryDir) Then
Exit Do
End If
Loop
' 配列aryDirの全フォルダについてファイルを取得し、配列aryFileへ
ReDim aryFile(0)
For i = 0 To UBound(aryDir)
strName = Dir(aryDir(i) & "\", vbNormal)
' strName = Dir(aryDir(i) & "\", vbNormal + vbHidden + vbReadOnly + vbSystem)
Do While strName <> ""
If Left(strName, 2) <> "~$" Then
If aryFile(0) <> "" Then
ReDim Preserve aryFile(UBound(aryFile) + 1)
End If
'2015/09/04 対象ファイルが存在しない時の不具合対応 ------------------->
'If (Right(strName, 3) = "xls" Or Right(strName, 4) = "xlsx") Then
If (LCase(Right(strName, 3)) = "xls" Or LCase(Right(strName, 4)) = "xlsx") Then
'2015/09/04 対象ファイルが存在しない時の不具合対応 ------------------->
' 戻り値用の配列に入れる
ReDim Preserve aryRet(intCount)
aryRet(intCount) = aryDir(i) & "\" & strName
intCount = intCount + 1
End If
End If
strName = Dir()
Loop
Next
対象ファイルが存在しない時の不具合対応 ------------------->
' If UBound(aryDir) > 0 Then
' ' 配列(ファイル名)をソートする
' For i = 0 To UBound(aryDir) ''ソート開始
' For j = UBound(aryDir) To i Step -1
' If aryRet(i) > aryRet(j) Then
' swap = aryRet(i)
' aryRet(i) = aryRet(j)
' aryRet(j) = swap
' End If
' Next j
' Next i
' End If
'ファイルが存在する場合
If intCount > 0 Then
' 配列(ファイル名)をソートする
For i = 0 To UBound(aryRet) ''ソート開始
For j = UBound(aryRet) To i Step -1
If aryRet(i) > aryRet(j) Then
swap = aryRet(i)
aryRet(i) = aryRet(j)
aryRet(j) = swap
End If
Next j
Next i
End If
対象ファイルが存在しない時の不具合対応 ------------------->
' 0件時
If Sgn(aryRet) = 0 Then
' InFileName = aryRet
InFileCount = 0
Exit Sub
Else
' 配列をセットして終了
InFileName = aryRet
' InFileCount = intCount - 1
InFileCount = intCount
Exit Sub
End If
Err_GetFiles:
ErrMSG = CStr(Err.Number) & ":" & Error
End Sub
' **************************************************
' 機能名:?A出力処理
' 機能概要 :定数で設定されたセルの内容をExcel形式で出力する
' 引数 :なし
' 戻値 :作成したテンポラリファイル名
' **************************************************
Public Function MakeExcel() As String
On Error GoTo Err_MakeExcel
' 変数宣言
Dim TempName As String ' テンポラリファイル名
Dim xlAppi As Excel.Application ' (入力用)Excelアプリ
Dim xlBooki As Excel.Workbook ' (入力用)ワークブック
Dim xlSheeti As Excel.Worksheet ' (入力用)処理対象シート
Dim xlAppo As Excel.Application ' (出力用)Excelアプリ
Dim xlBooko As Excel.Workbook ' (出力用)ワークブック
Dim xlSheeto As Excel.Worksheet ' (出力用)処理対象シート
Dim lngPutLine As LongPtr ' 出力行
Dim strLine_J As String ' 工程用ワーク
Dim strAtoJ As String ' 明細行用ワーク
Dim i As Long ' ループ用
Dim j As Long ' ループ用
Dim pos As Integer ' パスとファイル名の切り分け位置
Dim Fn As Integer ' ファイル番号
Dim tmp As Variant ' 区切り抽出用
Dim flag As Boolean ' シートの有無
Dim ws As Excel.Workbooks ' シートの有無検索用
' 変数定義
Err.Clear ' エラーを初期化
ErrMSG = "" ' エラーメッセージも一応初期化
' テンポラリファイル名を設定
TempName = TempFolder() & Replace(DEF_FILENAME, "%1%", Format(Now(), "yyyymmddhhMMss")) & ".xlsx"
'新規にブックを追加
Workbooks.Add
Dim strBookName As String
Dim objWorkBook As Workbook
Set objWorkBook = Workbooks.Application.ActiveWorkbook
strBookName = objWorkBook.Name
'アクティブにする
objWorkBook.Worksheets(OUT_SHEET_NAME).Select
' ヘッダ出力
With objWorkBook.Worksheets(OUT_SHEET_NAME)
.Range("A1").Value = ""
.Range("B1").Value = ""
.Range("C1").Value = ""
.Range("D1").Value = ""
.Range("E1").Value = ""
.Range("F1").Value = ""
.Range("G1").Value = ""
.Range("H1").Value = ""
.Range("I1").Value = ""
.Range("J1").Value = ""
.Range("K1").Value = "o"
.Range("L1").Value = ""
.Range("M1").Value = ""
.Range("N1").Value = ""
.Range("O1").Value = ""
.Range("P1").Value = ""
.Range("Q1").Value = ""
.Range("R1").Value = ""
.Range("S1").Value = ""
.Range("T1").Value = ""
.Range("U1").Value = ""
.Range("V1").Value = ""
.Range("W1").Value = ""
.Range("X1").Value = ""
.Range("Y1").Value = ""
.Range("Z1").Value = ""
End With
' 出力行の初期化
lngPutLine = 2
' セットされているカウンタ分ループ
For i = 0 To InFileCount - 1
j = 0 ' 明細ループ初期化
' Excel(出力)ファイルオープン
Set xlAppi = CreateObject("Excel.Application") ' Application生成
xlAppi.Workbooks.Open Filename:=InFileName(i), UpdateLinks:=0 ' EXCELを開く
xlAppi.Visible = False ' EXCELは表示しない
' シートのチェック
If Not Sheet_Check(InFileName(i), TARGET_SHEET) Then
' 対象シートが無い場合
MakeExcel = ""
' 対象外
GoTo DiffentFile
End If
' Excel(入力)ファイルオープン
Set xlBooki = xlAppi.Workbooks(Dir(InFileName(i))) ' Workbook
' 処理対象
Set xlSheeti = xlBooki.Worksheets(TARGET_SHEET) ' Worksheet
' 処理対象(セルA14=1)か?
If xlSheeti.Cells(14, 1).MergeArea.Cells(1, 1).Value = "1" Then
strLine_J = "" ' 不良発見工程用ワーク初期化
pos = InStrRev(InFileName(i), "\") ' ファイルとパスに分ける準備
With objWorkBook.Worksheets(OUT_SHEET_NAME)
.Range("A" & lngPutLine & ":A" & lngPutLine).Value = Left(InFileName(i), pos) ' Excel解析(A:フォルダ名)
.Range("B" & lngPutLine & ":B" & lngPutLine).Value = Mid(InFileName(i), pos + 1) ' Excel解析(B:ファイル名)
.Range("C" & lngPutLine & ":C" & lngPutLine).Value = xlSheeti.Cells.Range(IN_BADNO).Value ' Excel解析(C:不良番号)
.Range("D" & lngPutLine & ":D" & lngPutLine).Value = xlSheeti.Cells.Range(IN_ISSUE_DATE).Value ' Excel解析(D:発行年月日)
.Range("E" & lngPutLine & ":E" & lngPutLine).Value = xlSheeti.Cells.Range(IN_ORDER).Value ' Excel解析(E:オーダ)
.Range("F" & lngPutLine & ":F" & lngPutLine).Value = xlSheeti.Cells.Range(IN_ORDER_SOURCE).Value ' Excel解析(F:注文元)
.Range("G" & lngPutLine & ":G" & lngPutLine).Value = xlSheeti.Cells.Range(IN_SUBJECT).Value ' Excel解析(G:件名)
.Range("H" & lngPutLine & ":H" & lngPutLine).Value = xlSheeti.Cells.Range(IN_MODELS).Value ' Excel解析(H:機種)
.Range("I" & lngPutLine & ":I" & lngPutLine).Value = xlSheeti.Cells.Range(IN_DECENES).Value ' Excel解析(I:出検者)
' 複数選択を考慮
' *** 一番上 ***
If xlSheeti.Cells.Range(IN_PROD_OUT).Value <> "" Then
strLine_J = strLine_J & "製外先立会/"
End If
If xlSheeti.Cells.Range(IN_PRO_IN).Value <> "" Then
strLine_J = strLine_J & "製外品受入/"
End If
If xlSheeti.Cells.Range(IN_UNIT).Value <> "" Then
strLine_J = strLine_J & "ユニット検査/"
End If
' *** 真ん中 ***
If xlSheeti.Cells.Range(IN_BORD_INSP).Value <> "" Then
strLine_J = strLine_J & "盤検査/"
End If
If xlSheeti.Cells.Range(IN_MARKING_CONF).Value <> "" Then
strLine_J = strLine_J & "現品会議/"
End If
If xlSheeti.Cells.Range(IN_HD_TEST).Value <> "" Then
strLine_J = strLine_J & "H/W試験/"
End If
' *** 一番下 ***
If xlSheeti.Cells.Range(IN_SYSTEM_TEST).Value <> "" Then
strLine_J = strLine_J & "システム試験/"
End If
If xlSheeti.Cells.Range(IN_SHIPPING_INSP).Value <> "" Then
strLine_J = strLine_J & "出荷検査/"
End If
If xlSheeti.Cells.Range(IN_FIELD_TEST).Value <> "" Then
strLine_J = strLine_J & "現地試験"
End If
' 編集結果の最後にスラッシュがあれば削除
If Right(strLine_J, 1) = "/" Then
strLine_J = Left(strLine_J, LenB(strLine_J) - 1)
End If
.Range("J" & lngPutLine & ":J" & lngPutLine).Value = strLine_J ' Excel解析(J:不良発見工程)
' 明細は同じ行のA列〜J列をコピーして貼り付けする為退避
Range("A" & lngPutLine & ":J" & lngPutLine).Copy
' ここから明細行
' No(L)が入っている間明細ループ■■■■■■■■■■■■
Do While Trim(xlSheeti.Cells.Range(IN_NO & CStr((14 + j * 6))).Value) <> ""
' If j > 1 Then
' 2行目以降はA〜Jがないので追加
Range(lngPutLine & ":" & lngPutLine).PasteSpecial
' End If
.Range("K" & lngPutLine & ":K" & lngPutLine).Value = xlSheeti.Cells.Range(IN_NO & CStr((14 + j * 6))).Value ' Excel解析(K:NO(A14→A20と6刻み)
.Range("L" & lngPutLine & ":L" & lngPutLine).Value = xlSheeti.Cells.Range(IN_SPOILAGE & CStr(15 + j * 6)).Value ' Excel解析(L:仕損)
.Range("M" & lngPutLine & ":M" & lngPutLine).Value = xlSheeti.Cells.Range(IN_BURDEN & CStr(15 + j * 6)).Value ' Excel解析(M:負担)
.Range("N" & lngPutLine & ":N" & lngPutLine).Value = xlSheeti.Cells.Range(IN_PHENOMENON & CStr(18 + j * 6)).Value ' Excel解析(N:現象)*
.Range("O" & lngPutLine & ":O" & lngPutLine).Value = xlSheeti.Cells.Range(IN_NUM_DEFECTS & CStr(18 + j * 6)).Value ' Excel解析(O:不良数)*
.Range("P" & lngPutLine & ":P" & lngPutLine).Value = xlSheeti.Cells.Range(IN_PRODUCT & CStr(15 + j * 6)).Value ' Excel解析(P:品名)
' ここからは全部で1行なので別計算
.Range("Q" & lngPutLine & ":Q" & lngPutLine).Value = xlSheeti.Cells.Range(IN_TROUBLE_CONTENT & CStr(14 + j * 6)).Value ' Excel解析(Q:不具合内容/処置依頼事項)※
.Range("R" & lngPutLine & ":R" & lngPutLine).Value = xlSheeti.Cells.Range(IN_DEADLINE & CStr(14 + j * 6)).Value ' Excel解析(R:処置期限)
.Range("S" & lngPutLine & ":S" & lngPutLine).Value = xlSheeti.Cells.Range(IN_COR_NECECE & CStr(14 + j * 6)).Value ' Excel解析(S:是正要否)
.Range("T" & lngPutLine & ":T" & lngPutLine).Value = xlSheeti.Cells.Range(IN_TREATMENT & CStr(14 + j * 6)).Value ' Excel解析(T:処置・対策内容)※
.Range("U" & lngPutLine & ":U" & lngPutLine).Value = xlSheeti.Cells.Range(IN_TREATMENT_DAY & CStr(14 + j * 6)).Value ' Excel解析(U:処置日)
.Range("V" & lngPutLine & ":V" & lngPutLine).Value = xlSheeti.Cells.Range(IN_RELAP_PREVENT & CStr(14 + j * 6)).Value ' Excel解析(V:再発防止)※
.Range("W" & lngPutLine & ":W" & lngPutLine).Value = xlSheeti.Cells.Range(IN_TC_RESULT & CStr(14 + j * 6)).Value ' Excel解析(W:処置確認結果)※
.Range("X" & lngPutLine & ":X" & lngPutLine).Value = xlSheeti.Cells.Range(IN_DATE_CONFIR & CStr(14 + j * 6)).Value ' Excel解析(X:確認日)
.Range("Y" & lngPutLine & ":Y" & lngPutLine).Value = xlSheeti.Cells.Range(IN_CONFIR_PERSON & CStr(14 + j * 6)).Value ' Excel解析(Y:確認者)
.Range("Z" & lngPutLine & ":Z" & lngPutLine).Value = xlSheeti.Cells.Range(IN_TREATMENT_SECTION).Value ' Excel解析
j = j + 1
lngPutLine = lngPutLine + 1
Loop
End With
Else
' 対象外
GoTo DiffentFile
End If
' カーソルをA1に移動
Cells(1, 1).Select
skipFlg = True
DiffentFile:
' Excelファイルクローズ
xlAppi.Quit ' EXCELを閉じる(入力)
Set xlSheeti = Nothing ' オブジェクトの解放(入力)
Set xlBooki = Nothing ' オブジェクトの解放(入力)
Set xlAppi = Nothing ' オブジェクトの解放(入力)
Next
If skipFlg Then
' セルの調整
Columns("A:Y").EntireColumn.AutoFit ' 全体の自動調整
Columns(1).ColumnWidth = 25 ' フォルダ名の幅調整
Columns(2).ColumnWidth = 25 ' ファイル名の幅調整
'名前を付けて保存
objWorkBook.SaveAs TempName
End If
'閉じる
Application.DisplayAlerts = False
objWorkBook.Close
' クローズ
Set xlSheeto = Nothing ' オブジェクトの解放(出力)
Set xlBooko = Nothing ' オブジェクトの解放(出力)
Set xlAppo = Nothing ' オブジェクトの解放(出力)
MakeExcel = TempName
Exit Function
Err_MakeExcel:
ErrMSG = CStr(Err.Number) & ":" & Error
Set xlSheeti = Nothing ' オブジェクトの解放(入力)
Set xlBooki = Nothing ' オブジェクトの解放(入力)
Set xlAppi = Nothing ' オブジェクトの解放(入力)
Set xlSheeto = Nothing ' オブジェクトの解放(出力)
Set xlBooko = Nothing ' オブジェクトの解放(出力)
Set xlAppo = Nothing ' オブジェクトの解放(出力)
MakeExcel = ""
End Function
' **************************************************
' 機能 :WindowsのTempフォルダの取得
' 戻値 :WindowsのTempフォルダ
' **************************************************
Private Function TempFolder() As String
Dim FolderName As String
FolderName = Space(MAX_PATH)
Call GetTempPath(LenB(FolderName), FolderName)
TempFolder = Left(FolderName, InStr(1, FolderName, vbNullChar) - 1)
End Function
' **************************************************
' 機能 :Excelのシートの有無をチェック
' 引数 :なし
' 戻値 :True=あり
' **************************************************
Function Sheet_Check(Book As String, Sheet As String) As Boolean
Dim rt As Boolean
Dim fs As Object
' ファイルシステムオブジェクト
Set fs = CreateObject("Scripting.FileSystemObject")
rt = False ' 存在しない
If (fs.FileExists(Book)) Then
Workbooks.Open Filename:=Book ' 引数のブックをオープン
'Windows(Book).Activate
rt = True
On Error GoTo SheetErr
Sheets(Sheet).Select
On Error GoTo 0
ActiveWindow.Close
End If
Set fs = Nothing
Sheet_Check = rt
Exit Function
SheetErr:
rt = False
Resume Next
End Function
(マツ) 2020/11/27(金) 17:34
Public Const E04 As String = "対象のファイルが存在しません。"←このエラーメッセージが表示します。 今度は E04 が宣言以外に存在しません。
エラーを起こしている場所がなければ答えようがないでしょう。
ここまで長いと全文読んで解読しようという気にもなりません。
きりがないので、私は下ります。
(通りすがりの) 2020/11/27(金) 20:05
[ 一覧(最新更新順) ]
YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki.
Modified by kazu.