Board logo

標題: [發問] 選擇檔案轉成文字檔問題. [打印本頁]

作者: dou10801    時間: 2023-10-30 10:45     標題: 選擇檔案轉成文字檔問題.

1.選檔[21.XLSX]轉成21.TXT可以,為何選檔[22.XLSX]轉成22.TXT不行,問題在那裡?
2.可否[指定工作表]:
MP1=Range(“B7”)
'With Workbooks.Open(xlsPath, , True).Sheets(MP1)  '如何指定工作表=>不行
With Workbooks.Open(xlsPath, , True).Sheets(1)         '可行.
作者: Andy2483    時間: 2023-10-30 11:08

本帖最後由 Andy2483 於 2023-10-30 11:16 編輯

回復 1# dou10801


方法1.:
With Workbooks.Open(xlsPath, , True).Sheets(Val(MP1))
"3"是字串,指定3索引號工作表必須將字串 "3" 轉化為數值 3
[attach]36932[/attach]

方法2.:
宣告為短整數:
    Dim MP1%
    MP1 = Range("B7")
    With Workbooks.Open(xlsPath, , True).Sheets(MP1)
[attach]36933[/attach]
作者: dou10801    時間: 2023-10-30 11:32

回復 2# Andy2483 感謝前輩回覆,21-1.TXT是我須求的完成檔,改With Workbooks.Open(xlsPath, , True).Sheets(Val(MP1))後,產生21.TXT的檔案內容會變成 2.58003E+50
2.58003E+50
2.58003E+50
2.58003E+50
2.58003E+50
2.58003E+50
2.58003E+50
2.58003E+50
2.58003E+50
2.58003E+50
作者: Andy2483    時間: 2023-10-30 11:53

回復 3# dou10801


   
mcs = "'" & mcs1 & Cells(R, MDS2) & Format(Cells(R, MDS3),~~
作者: dou10801    時間: 2023-10-30 12:13

回復 4# Andy2483 會不會是版本問題,我的是2010版,還是不行.
作者: Andy2483    時間: 2023-10-30 12:23

本帖最後由 Andy2483 於 2023-10-30 12:25 編輯

回復 5# dou10801


    選22 結果:
[attach]36935[/attach]

結果不行?還是過程錯誤?
作者: dou10801    時間: 2023-10-30 12:31

回復 6# Andy2483 感謝前輩多次回覆,我產生檔是這樣.
作者: Andy2483    時間: 2023-10-30 13:06

回復 7# dou10801


   
With Workbooks.Open(xlsPath, , True).Sheets(1)
      .Cells.NumberFormatLocal = "@"
      Arr = .[A1].CurrentRegion
      brr = .[A1].CurrentRegion
~~
作者: dou10801    時間: 2023-10-30 13:18

回復 8# Andy2483
With Workbooks.Open(xlsPath, , True).Sheets(1)
      .Cells.NumberFormatLocal = "@"
取第一工作表正常了.


With Workbooks.Open(xlsPath, , True).Sheets(2)    或   With Workbooks.Open(xlsPath, , True).Sheets(val(mp1)
      .Cells.NumberFormatLocal = "@"
這個還是不行...........
作者: Andy2483    時間: 2023-10-30 13:37

回復 9# dou10801


    With Workbooks.Open(xlsPath, , True).Sheets(2) 執行結果 怎樣不行?
作者: dou10801    時間: 2023-10-30 13:48

本帖最後由 dou10801 於 2023-10-30 13:51 編輯

回復 10# Andy2483
With Workbooks.Open(xlsPath, , True).Sheets(2)
1.選取22.XLSX為例.
2,會產生[工作表一]的資料,且不是字串組合.
mcs = "" & mcs1 & Cells(R, MDS2) & Format(Cells(R, MDS3), "00000000000") & "00" & mcs2 & Cells(R, MDS4) & String(p2, " ")
作者: Andy2483    時間: 2023-10-30 13:59

回復 11# dou10801


   
With Workbooks.Open(xlsPath, , True).Sheets(2)
       .Activate
      .Cells.NumberFormatLocal = "@"
      Arr = .[A1].CurrentRegion
      brr = .[A1].CurrentRegion

[attach]36940[/attach]
作者: dou10801    時間: 2023-10-30 14:24

回復 12# Andy2483
方法1.:
With Workbooks.Open(xlsPath, , True).Sheets(Val(MP1))
"3"是字串,指定3索引號工作表必須將字串 "3" 轉化為數值 3

方法2.:
宣告為短整數:
Dim MP1%
MP1 = Range("B7")
With Workbooks.Open(xlsPath, , True).Sheets(MP1)

mcs = "'" & mcs1 & Cells(R, MDS2) & Format(Cells(R, MDS3),~~

With Workbooks.Open(xlsPath, , True).Sheets(2)
    .Activate
  .Cells.NumberFormatLocal = "@"

此次問答,感謝前輩,不吝賜教指導,學到很多小細節,感恩感恩.
作者: Andy2483    時間: 2023-10-30 14:33

回復 13# dou10801


    將每個變數都做宣告 可以讓邏輯更清楚,建議養成習慣
作者: dou10801    時間: 2023-10-30 15:03

回復 14# Andy2483
以選22.XLSX,第3工作表為例,末筆資料,[合計]字樣為何拿不掉.請前輩指點,謝謝.
If Cells(R, 3) <> "" Then    '已判斷C欄空白不加入BRR(),但產生檔還是有[合計]字樣.
            p1 = Len(Cells(R, MDS4))  '備註欄長度.
            p2 = 29 - p1              '補空白長度
            mcs = "" & mcs1 & Cells(R, MDS2) & Format(Cells(R, MDS3), "00000000000") & "00" & mcs2 & Cells(R, MDS4) & String(p2, " ")
            brr(R, 1) = mcs
          End If
作者: Andy2483    時間: 2023-10-30 15:23

回復 15# dou10801


   
      Arr = .[A1].CurrentRegion
      'brr = .[A1].CurrentRegion
      ReDim brr(1 To UBound(Arr), 1 To 1)
      'MsgBox UBound(Arr)
      For R = 1 To UBound(Arr)
作者: Andy2483    時間: 2023-10-31 09:44

回復 1# dou10801


    以下是練習的方案,請前輩參考

Option Explicit
Sub 按鈕1_Click()
Application.DisplayAlerts = False
Dim MyFile, Arr, Brr$(), p2%, myPath$, R&, Q, MDS$(2 To 4), Nm$, Sc%, mcs1$, mcs2$
MyFile = Application.GetOpenFilename("Excel檔,*.XLS*")
If MyFile = "False" Then Exit Sub
Q = Split([B6], ",")
myPath = ThisWorkbook.Path & "\"
mcs1 = [B1] & Mid([B2], 2, 6) & [B3] & [B4]
mcs2 = [B5]: Sc = Val([B7])
With Workbooks.Open(MyFile, , True)
   Nm = .Name
   If Sc > .Worksheets.Count Then MsgBox Nm & " 活頁簿沒有第" & Sc & " 個表": .Close 0: Exit Sub
   With .Sheets(Sc)
      If Not .AutoFilter Is Nothing Then If .FilterMode = True Then .ShowAllData
      Arr = Range(.[G1], .[A65536].End(3))
   End With
   .Close 0
End With
If UBound(Arr) = 1 Then MsgBox Nm & " 活頁簿第" & Sc & " 個表沒有資料": Exit Sub
ReDim Brr(1 To UBound(Arr) - 1, 1 To 1)
For R = 2 To UBound(Arr)
   If Arr(R, 3) <> "" Then
      p2 = 29 - Len(Arr(R, Val(Q(2))))
      MDS(2) = Arr(R, Val(Q(0)))
      MDS(3) = Format(Arr(R, Val(Q(1))), "00000000000")
      MDS(4) = Arr(R, Val(Q(2)))
      Brr(R - 1, 1) = mcs1 & MDS(2) & MDS(3) & "00" & mcs2 & MDS(4) & String(p2, " ")
   End If
Next R
Workbooks.Add
[A1].Resize(UBound(Arr) - 1, 1) = Brr
Nm = StrReverse(Mid(StrReverse(Nm), InStr(StrReverse(Nm), ".") + 1))
ActiveWorkbook.SaveAs myPath & Nm & ".TXT", 42
ActiveWindow.Close
ThisWorkbook.Activate
MsgBox "產生媒體檔:" & myPath & Nm & ".TXT"
End Sub
作者: dou10801    時間: 2023-10-31 11:56

回復 17# Andy2483
學到另一種方式,感激不盡.
作者: Andy2483    時間: 2023-10-31 14:45

謝謝論壇,謝謝各位前輩
以下心得註解,請各位前輩指教

Option Explicit
Sub 按鈕1_Click()
Application.DisplayAlerts = False
'↑令執行到是否儲存取代舊檔時,不跳出詢問窗,直接取代儲存
Dim MyFile, Arr, Q, Brr$(), R&, Sc%, p2%, MDS$(2 To 4), mcs1$, mcs2$, Nm$, myPath$
'↑宣告變數:(MyFile,Arr,Q)是通用型變數,Brr是陣列(陣列值為字串),R是長整數,
'(Sc,p2)是短整數,MDS是一維陣列(索引號2~4),(mcs1, mcs2,Nm,myPath)是字串變數

MyFile = Application.GetOpenFilename("Excel檔,*.XLS*")
'↑令MyFile這通用型變數是 顯示標準的 [開啟舊檔] 對話方塊,從使用者取得檔案的名稱
https://learn.microsoft.com/zh-t ... ion.getopenfilename
If MyFile = False Then Exit Sub
'↑如果MyFile變數是邏輯值 False,代表沒有選取檔案,結束程序執行
Q = Split([B6], ",")
'↑令Q這通用型變數是[B6]儲存格以 逗號分割成的一維陣列
myPath = ThisWorkbook.Path & "\"
'↑令myPath這字串變數是 本活頁簿所在的路徑連接 "\"所組成的字串
mcs1 = [B1] & Mid([B2], 2, 6) & [B3] & [B4]
'↑令mcs1這字串變數是 [B1]儲存格值,連接[B2]儲存格值取第2字元開始的6字元字串,
'再連接[B3]儲存格值,最後連接[B4]儲存格值,組合成的字串

mcs2 = [B5]: Sc = Val([B7])
'↑令mcs2這字串變數是 [B5]儲存格值字串
'令Sc這短整數是 [B7]儲存格值轉化的整數值

If Sc <= 0 Then MsgBox "[B7]儲存格輸入錯誤": Exit Sub
'↑如果Sc變數小於或等於0!,就跳出提示窗~~~,結束程序執行
With Workbooks.Open(MyFile, , True)
'↑以下是關於 無密碼/唯讀/開啟MyFile變數 舊檔的相關程序
   Nm = .Name
   '↑令Nm這字串變數是 這開啟檔案名字字串
   If Sc > .Worksheets.Count Then MsgBox Nm & " 活頁簿沒有第" & Sc & " 個表": .Close 0: Exit Sub
   '↑如果Sc變數大於此舊檔工作表數量!就跳出提視窗~~~,關閉檔案(不儲存),結束程序執行
   With .Sheets(Sc)
   '↑以下是關於此舊檔的第 Sc變數個工作表的相關程序
      If Not .AutoFilter Is Nothing Then If .FilterMode = True Then .ShowAllData
      '↑如果有篩選功能!就判斷如果是篩選狀態!令清除篩選
      Arr = Range(.[G1], .[A65536].End(3))
      '↑令Arr這通用型變數是 二維陣列,以該表的[G2]到A欄最後有內容的儲存格,
      '此範圍儲存格值帶入陣列中

   End With
   .Close 0
   '↑令該舊檔關閉(不儲存)
End With
If UBound(Arr) = 1 Then MsgBox Nm & " 活頁簿第" & Sc & " 個表沒有資料": Exit Sub
'↑如果Arr陣列縱向最大索引列號是 1!就跳出提視窗~~~,結束程序執行
ReDim Brr(1 To UBound(Arr) - 1, 1 To 1)
'↑宣告Brr陣列縱向範圍從索引號1 到Arr陣列縱向最大索引列號-1,橫向範圍從1~1索引號
For R = 2 To UBound(Arr)
'↑設順迴圈!令R變數從2 到Arr陣列縱向最大索引列號
   If Arr(R, 3) <> "" Then
   '↑如果R迴圈列第3欄Arr陣列值不是空字元?
      p2 = 29 - Len(Arr(R, Val(Q(2))))
      '↑令p2這短整數變數是 29-(迴圈陣列值的字元數)
      '迴圈陣列值:(R迴圈列,2索引號Q陣列值轉為數值的欄號)Arr陣列值

      MDS(2) = Arr(R, Val(Q(0)))
      '↑令2索引號MDS陣列值是 (R迴圈索引列,0索引號Q陣列值轉為數值的索引欄號)Arr陣列值
      MDS(3) = Format(Arr(R, Val(Q(1))), "00000000000")
      '↑令3索引號MDS陣列值是 (R迴圈索引列,1索引號Q陣列值轉為數值的索引欄號)Arr陣列值,
      '再將此值轉化為 "00000000000"格式的字串

      MDS(4) = Arr(R, Val(Q(2)))
      '↑令4索引號MDS陣列值是 (R迴圈索引列,2索引號Q陣列值轉為數值的索引欄號)Arr陣列值
      Brr(R - 1, 1) = mcs1 & MDS(2) & MDS(3) & "00" & mcs2 & MDS(4) & String(p2, " ")
      '↑令(R迴圈-1)列1欄Brr陣列值是 接續多個字串組成的字串
      'String(p2, " "):是p2個空白字元的字串

   End If
Next R
Workbooks.Add
'↑令新增一個活頁簿
[A1].Resize(UBound(Arr) - 1, 1) = Brr
'↑令[A1]儲存格擴展向下(Arr陣列縱向最大索引號-1)列的範圍儲存格值以Brr陣列值帶入
Nm = StrReverse(Mid(StrReverse(Nm), InStr(StrReverse(Nm), ".") + 1))
'↑令Nm變數字串反轉後 取"."後(不含)的所有字元,再反轉回來
ActiveWorkbook.SaveAs myPath & Nm & ".TXT", 42
'↑令儲存為 文字字檔(Unicode 文字)
https://learn.microsoft.com/zh-t ... /excel.xlfileformat
ActiveWindow.Close
'↑令此視窗活頁簿 關閉
ThisWorkbook.Activate
'↑激活本檔
MsgBox "產生媒體檔:" & myPath & Nm & ".TXT"
'↑跳出提示窗 ~~~
End Sub
作者: 准提部林    時間: 2023-10-31 20:03

參考檔//
[attach]36941[/attach]
作者: dou10801    時間: 2023-11-1 09:02

回復 20# 准提部林
感謝:准提部林,指導.代碼給初學者更清楚學習,感恩.
作者: Andy2483    時間: 2023-11-2 11:38

本帖最後由 Andy2483 於 2023-11-3 07:20 編輯

回復 20# 准提部林


    謝謝論壇,謝謝前輩指導
以下是懵懂的心得註解,請前輩再指導

Sub Test_a1()
Dim xFile$, T1$, T2$, BN$, SN$, P$, PP$, Sx%, Cn, Arr, i&
'↑宣告變數:(xFile,T1,T2,BN,SN,P,PP)是字串變數,Sx是短整數變數,
'(Cn,Arr)是通用型變數,i是長整數變數

ChDir ThisWorkbook.Path
'↑ChDir "D:\"  '指定開啟檔案的路徑
xFile = Application.GetOpenFilename("Excel檔,*.XLS*")
'↑令xFile這字串變數是 顯示標準的 [開啟舊檔] 對話方塊,從使用者取得檔案的名稱
If xFile = "False" Then Exit Sub
'↑如果xFile變數是字串"False",代表沒有選取檔案,結束程序執行
T1 = [b1] & Mid([b2], 2, 6) & [b3] & [b4]
'↑令mcs1這字串變數是 [b1]儲存格值,連接[b2]儲存格值取第2字元開始的6字元字串,
'再連接[b3]儲存格值,最後連接[b4]儲存格值,組合成的字串 (文字串前碼)

T2 = [b5]
'↑令T2這字串變數是[b5]儲存格值 (存提款代號)
Sx = Val([b7])
'↑令Sx這字串變數是 [b7]儲存格值轉化的整數值 (指定第?張工作表(依左而右順序))
Cn = Split([b6], ",")
'↑令Cn這通用型變數是 [b6]儲存格以 逗號分割成的一維陣列 (指定欄位)
'---------------------------------

On Error Resume Next
'↑令程序執行不偵錯
With GetObject(xFile)
'↑以下是關於以xFile變數用GetObject函式 回傳物件(活頁簿)的程序
'謝謝 前輩指導這函式的用法
'執行到這裡並沒有看到開啟活頁簿,很神奇!後來查看到活頁簿視窗被隱藏起來了


'如果該活頁簿原本就被開啟會直接指向此活頁簿,不會再重新開啟一次
https://learn.microsoft.com/zh-t ... /getobject-function
     BN = Split(.Name, ".")(0)
     '↑令BN這字串變數是 活頁簿檔名(去除副檔名)
     '(去除副檔名方法:以"."符號分割活頁簿名稱,取0索引號陣列值)

     SN = .Sheets(Sx).Name
     '↑令SN這字串變數是活頁簿裡第Sx變數索引號工作表名稱
     Arr = Range(.Sheets(Sx).[g1], .Sheets(Sx).UsedRange) '資料範圍(含G欄)
     '↑令Arr這通用型變數是二維陣列,以已使用儲存格(含G欄)範圍儲存格值帶入
     .Close 0
     '↑令活頁簿關閉(不儲存)
End With
On Error GoTo 0
'↑令程序恢復偵錯
If SN = "" Then MsgBox "指定工作表不存在!  ": Exit Sub
'↑如果SN變數是 空的!就跳出提視窗~~~ ,結束程序執行
'----------------------------------

For i = 2 To UBound(Arr)
'↑設順迴圈!i從2 到Arr陣列縱向最大索引列號
    P = T1 & Arr(i, Cn(0))
    '↑令P這字串變數是 T1變數連接 i迴圈列(0索引號Cn陣列值)欄Arr陣列值
    P = P & Format(Arr(i, Cn(1)), "00000000000;;#") & "00" & T2
    '↑令P變數再連接 i迴圈列(1索引號Cn陣列值)欄Arr陣列值以Format函式回傳字串,
    '再連接 "00",續連接T2變數
    '這;;#分區段現在還不能理解,需要更多學習

    https://learn.microsoft.com/zh-t ... ic-for-applications
    P = P & Left(Arr(i, Cn(2)) & String(29, " "), 29)
    '↑令P變數再連接 29個字元的字串:
    'i迴圈列(2索引號Cn陣列值)欄Arr陣列值 連接29個空白字元,所組成的新字串,取左側29個字元

    If Len(P) = 80 Then PP = PP & IIf(PP = "", "", vbCrLf) & P
    '↑如果P變數字元數是80!就令PP這字串變數累增加字串(歸位字元換行組合)間隔
    '文字檔(.Txt)檔需要vbCrLf = CHR(13)+CHR(10) 才會換行

    https://learn.microsoft.com/zh-t ... ellaneous-constants
i01: Next i
If PP = "" Then MsgBox "指定工作表無符合資料!  ": Exit Sub
'↑如果PP變數是空的!就跳出提視窗~~~ ,結束程序執行
'----------------------------------

xFile = ThisWorkbook.Path & "\" & BN & "-Sheets(" & Sx & ").TXT"
Open xFile For Output As #1  'Output覆蓋舊資料
'↑以順序輸入模式開啟 檔案
https://learn.microsoft.com/en-u ... help/open-statement
Print #1, PP
'↑將顯示格式化資料 覆蓋舊資料寫入檔案
https://learn.microsoft.com/zh-t ... help/printstatement
Close #1
'↑關閉檔案
MsgBox "文字檔已建立:" & xFile
End Sub
作者: Andy2483    時間: 2023-11-2 15:22

回復 20# 准提部林


    請教前輩
1.Format(Arr(i, Cn(1)), "00000000000;;#")是指  [正數;負數;0;本文]
1.1.如果Arr(i, Cn(1))值是正數就以11位數呈現(不足部分用0填充在左側)
1.2.如果Arr(i, Cn(1))值是負數就以空格呈現
是這樣的意義嗎?

2.請教前輩這最後的  ;# 是什麼意思?

謝謝前輩
作者: 准提部林    時間: 2023-11-2 15:53

回復 23# Andy2483

只對"正數"及"零值"做規範, 零值為"空", 試試儲存格設為"#", 再輸入0
若也要將"負數"變成空字串
MsgBox Format(-1500, "00000000000;"""";#")
但對第四參數"文字"的顯示方式無法變更,
最理想還是用APPLICATION.TEXT(數字或文字, "正;負;0;文字")
作者: Andy2483    時間: 2023-11-2 16:16

本帖最後由 Andy2483 於 2023-11-3 07:27 編輯

回復 24# 准提部林


    謝謝前輩,請前輩再指導
1. 後學學到的是 ;; 兩個分號代表的是跳過負數的判斷,直接判斷是不是0
2.後學對 # 符號在Format()裡的意義不了解
例如:Format(Arr(i, Cn(1)), "00000000000;;""""") 與
Format(Arr(i, Cn(1)), "00000000000;;#")
這兩個有何不同?

'==========================================
學習補充:
(#)數字預留位置。 會顯示數字或不顯示任何項目。 如果運算式有數字位在格式字串中出現 # 的位置,
則顯示該字元;否則在該位置不顯示任何項目。 此符號的作用就像 0 數字預留位置,不同之處在於,
如果在格式運算式中,數字在小數分隔符號任一邊的位數,與 # 字元的位數相同或更少,
則不會顯示前置零或行尾零。
https://learn.microsoft.com/zh-t ... ic-for-applications

謝謝論壇,謝謝各位前輩
作者: Andy2483    時間: 2023-11-3 08:30

本帖最後由 Andy2483 於 2023-11-3 09:18 編輯

回復 24# 准提部林


    謝謝前輩指導,以下Application.Text()學習心得如下,請前輩再指導

Option Explicit
'最理想還是用APPLICATION.TEXT(數字或文字,"正;負;0;文字")
'VBA中呼叫工作表中的TEXT函數

Sub TEST_Text_1區段()
MsgBox Application.Text(10, "0000")
MsgBox Application.Text(-1.2, "0000")
MsgBox Application.Text(0, "0000")
End Sub

Sub TEST_Text_2區段()
MsgBox Application.Text(0, "000;-0.00")
MsgBox Application.Text(10, "000;-0.00")
MsgBox Application.Text(9999, "000;-0.00")
MsgBox Application.Text(-1, "000;-0.00")
MsgBox Application.Text(-10.1111, "000;-0.00")
End Sub

Sub TEST_Text_3區段()
MsgBox Application.Text(0, "000;-0.00;0")
MsgBox Application.Text(10, "000;-0.00;0")
MsgBox Application.Text(9999, "000;-0.00;0")
MsgBox Application.Text(-1, "000;-0.00;0")
MsgBox Application.Text(-10.1111, "000;-0.00;0")
MsgBox Application.Text(-10.1111, "000;倒扣了;0")
End Sub
Sub TEST_Text_4區段()
MsgBox Application.Text(0, "0000;-0.00;零;輸入錯誤")
MsgBox Application.Text(10, "0000;-0.00;零;輸入錯誤")
MsgBox Application.Text(9999, "0000;-0.00;零;輸入錯誤")
MsgBox Application.Text(-1, "0000;-0.00;零;輸入錯誤")
MsgBox Application.Text(-10.1111, "0000;-0.00;零;輸入錯誤")
End Sub

Sub TEST_Text_4區段_0()
MsgBox Application.Text(0, "0000;-0.00;;輸入錯誤")
MsgBox Application.Text(0, "0000;-0.00;0;輸入錯誤")
MsgBox Application.Text(0, "0000;-0.00;#;輸入錯誤")
MsgBox Application.Text(0, "0000;-0.00;取消;輸入錯誤")
MsgBox Application.Text("0o", "0000;-0.00;零;輸入錯誤")
'↑APPLICATION.TEXT(數字或文字,"正值格式;負值格式;想要的文字格式1;想要的文字格式2")
'如果 數字或文字是正數 ,令以正值格式回傳
'否則如果 數字或文字是負數,令負值格式回傳
'否則如果 數字或文字是0,令以想要的文字格式1回傳
'否則如果前面3個條件都不成立,令以想要的文字格式2回傳

End Sub

==============================================
在儲存格格式應用的方式如下:
[attach]36945[/attach]




歡迎光臨 麻辣家族討論版版 (http://forum.twbts.com/)