作者: sbg 時間: 2024-6-28 23:08 標題: 再請教excel問題
原始 Data好亂下
長度不一 首幾個喺Product ID打後就喺名稱
現想要統一番格式
總長度30
首六位喺數字唔夠要在前補0
其餘喺產品名稱 尾補space
先行謝謝
https://h2.hkepc.com/forum/attachment.php?aid=2429465&k=e57652853a70bee00dd86cd06b803fb1&t=1781622090&sid=38c5GmSjla

作者: jimking332 時間: 2024-6-29 18:46
回覆 1# sbg
呢個應該要VBA先搞得掂
作者: sbg 時間: 2024-6-30 23:09
Thanks ching
咁樣有無辦法可以取下左邊的數值
由0至6位長度沒有特定的
作者: jimking332 時間: 2024-6-30 23:16
用vba咪得囉
作者: sbg 時間: 2024-6-30 23:18
小弟才疏學淺唔曉

作者: lamsir 時間: 2024-7-1 15:10
本帖最後由 lamsir 於 2024-7-1 15:54 編輯
唔駛用 VBA,一條 Formula已搞掂
- =LEFT(TEXT(LEFT(A2,MIN(IF(ISNUMBER(--MID(A2,ROW(INDIRECT("1:6")),1)),999,ROW(INDIRECT("1:6"))))-1),"000000") & MID(A2,MIN(IF(ISNUMBER(--MID(A2,ROW(INDIRECT("1:6")),1)),999,ROW(INDIRECT("1:6")))),LEN(A2)) & REPT(" ", 30), 30)
作者: bongbong3481 時間: 2024-7-2 07:04
留名學野
作者: sbg 時間: 2024-7-2 10:48
Very NICE
Thanks ching
想請教一下Ctrl + Shift + Enter有乜唔同
直接enter結果與原本無分別
用咗Ctrl + Shift + Enter就能顯示正確結果
作者: peter_chan 時間: 2024-7-2 14:27
本帖最後由 peter_chan 於 2024-7-2 14:28 編輯
Very NICE
Thanks ching
想請教一下Ctrl + Shift + Enter有乜唔同
直接enter結果與原本無分別
用咗Ctrl ...
sbg 發表於 2024-7-2 10:48
M$ Execl 我唔清楚﹐因為我一直都無用新版的M$ Excel。
但google sheet﹐我就一直有用。
你想C欄得出 A+B欄的結果﹐傳統做法﹐你需要不停打....
=A1+B1
=A2+B2
=A3+B3
=A4+B4
一直打﹐按你需要一直打落去/拉落去。
但係﹐Array Formula 就只需在第一格打就可以。
你在第一格打 :
=A1:A+B1:B
再按 Ctrl+Shift+Enter
佢就會自動轉成 :
=ArrayFormula(A1:A+B1:B)
成個C欄﹐都會自動係A欄+B欄的結果。
唔再需要C欄每一格都輸入formula。
=ArrayFormula(A1:A+B1:B)
當中紅字位置﹐就係你需要的結尾位置。
Google 唔打結尾的位置﹐即係代表成欄都填滿。
M$ Excel 好似一定要講明結尾位置﹐例如做10行(如下)。
=ArrayFormula(A1:A10+B1:B10)
作者: platinum 時間: 2024-7-2 17:03
本帖最後由 platinum 於 2024-7-2 17:07 編輯
這裡也有一些相關的formula
https://www.ablebits.com/office- ... number-from-string/
作者: lamsir 時間: 2024-7-2 17:45
Very NICE
Thanks ching
想請教一下Ctrl + Shift + Enter有乜唔同
直接enter結果與原本無分別
用咗Ctrl ...
sbg 發表於 2024-7-2 10:48
我嘗試逐步解釋這條公式同點解要用Array Formula:
1. MID(A2,ROW(INDIRECT("1:6")),1)
這部分的目的是從儲存格A2中提取出前6個字符。ROW(INDIRECT("1:6"))會生成一個包含數字1到6的數字陣列,而MID(A2,ROW(INDIRECT("1:6")),1)則會從A2中逐個提取這6個位置的字符。
2. ISNUMBER(--MID(A2,ROW(INDIRECT("1:6")),1))
這部分是檢查上一步提取的每個字符是否為數字。使用--將字符轉換為數字,然後使用ISNUMBER函數檢查是否為數字。
3. IF(ISNUMBER(--MID(A2,ROW(INDIRECT("1:6")),1)),999,ROW(INDIRECT("1:6")))
這部分是創建一個數字陣列,該陣列的元素對應到前6個字符是否為數字。如果字符是數字,則對應的元素設為999,否則將對應的元素設為該字符所在的行數。
4. MIN(IF(ISNUMBER(--MID(A2,ROW(INDIRECT("1:6")),1)),999,ROW(INDIRECT("1:6"))))-1
這部分是找到上一步所創建的數字陣列中的最小值(除去999)。然後減去1以獲得最小值的前一個位置。
5. LEFT(A2,MIN(...)-1)
這部分是從儲存格A2中提取出從開頭到上一步找到的位置之前的字符。
6. TEXT(LEFT(...), "000000")
這部分是將上一步提取的字符轉換為固定長度的文字,該文字的長度為6位,不足6位的部分在前面補 0。
7. MID(A2,MIN(...)-1,LEN(A2))
這部分是從儲存格A2中提取出上一步找到的位置之後的所有字符。
8. REPT(" ", 30)
這部分是創建30個空格。
9. 最前的LEFT(... & ... & ..., 30)
這部分將前面提到的三個部分連接在一起,並截取前30個字符。如果連接後的文字長度不足30,則在後面補上空格。
由於第 1, 3 ,4部份都會返回數字陣列(Array),如公式中其他函數要逐個處理陣列中的數值,就必需輸入完後按下 Ctrl+Shift+Enter來告訴 Excel這是一個陣列公式。相反,如果按下普通的 Enter鍵,公式將被視為普通的儲存格公式,僅會處理返回數字陣列的第一個元素。
作者: sbg 時間: 2024-7-2 22:05
我嘗試逐步解釋這條公式同點解要用Array Formula:
1. MID(A2,ROW(INDIRECT("1:6")),1)
這部分的目的是 ...
lamsir 發表於 2024-7-2 17:45
冇得彈
逐個解釋非常清晰
作者: sbg 時間: 2024-7-2 22:06
Thx ching
作者: sbg 時間: 2024-7-2 22:06
thx ching
作者: DennisTan 時間: 2024-7-4 22:43
我嘗試逐步解釋這條公式同點解要用Array Formula:
1. MID(A2,ROW(INDIRECT("1:6")),1)
這部分的目的是 ...
lamsir 發表於 2024-7-2 17:45
勁!!!
作者: s20012797 時間: 2024-7-5 12:59
本帖最後由 s20012797 於 2024-7-5 13:02 編輯
VBA
- Sub FormatData()
- Dim lastRow As Long
- Dim i As Long
-
- ' 找到最後一行數據
- lastRow = Cells(Rows.Count, "A").End(xlUp).Row
-
- ' 遍歷每一行數據
- For i = 1 To lastRow
- ' 提取產品 ID 的前 6 位數字,並補零到 6 位
- Cells(i, "B").Formula = "=LEFT(TEXT(LEFT(A" & i & ",MIN(IF(ISNUMBER(--MID(A" & i & ",ROW(INDIRECT(""1:6"")),1)),999,ROW(INDIRECT(""1:6"")))})-1),""000000"")&MID(A" & i & ",MIN(IF(ISNUMBER(--MID(A" & i & ",ROW(INDIRECT(""1:6"")),1)),999,ROW(INDIRECT(""1:6"")})),LEN(A" & i & ")),LEN(A" & i & ")-MIN(IF(ISNUMBER(--MID(A" & i & ",ROW(INDIRECT(""1:6"")),1)),999,ROW(INDIRECT(""1:6"")})))+1)&REPT("" "", 30-LEN(Cells(i,""B"").Formula))"
- ' 將結果填入 B 列
- Cells(i, "B").Value = Cells(i, "B").Formula
- Next i
-
- ' 調整列寬
- Range("A:B").EntireColumn.AutoFit
- End Sub
- import re
- # 讀取資料
- data = []with open('input_file.txt', 'r') as file:
- for line in file:
- data.append(line.strip())
- # 格式化數據
- for i, row in enumerate(data):
- # 提取產品 ID 的前 6 位數字,並補零到 6 位
- product_id = row[:6].zfill(6) + row[6:]
- data[i] = product_id.ljust(30)
- # 寫入輸出檔案
- with open('output_file.txt', 'w') as file:
- file.writelines([line + '\n' for line in data])
- # 調整列寬
- print("資料已成功格式化,列寬已自動調整。")

作者: sbg 時間: 2024-7-5 16:34
跟之前 lamsir ching做法已經成功
但都想學吓VBA
THANK ching
作者: ivanyung 時間: 2024-7-6 22:33
本帖最後由 ivanyung 於 2024-7-7 08:11 編輯
- =LEFT(REPT("0",6-LEN(-LOOKUP(,-LEFT(A2,ROW($1:$6)))))&A2&REPT(" ",30),30)

作者: ivanyung 時間: 2024-7-7 11:03
還是習慣性用 VBA

工具,引用 .... Microsoft VBscript regular expression
- Function AddZero(MyStr As String) As String
-
- Dim MyRegEx As New RegExp
- MyRegEx.Pattern = "^[0-9]{1,6}"
-
- Dim NewLen As Integer
- NewLen = Len(MyRegEx.Replace(MyStr, ""))
-
- MyStr = String(6 - Len(MyStr) + NewLen, "0") & MyStr & String(30, " ")
-
- AddZero = Left(MyStr, 30)
-
- End Function
- =Addzero(a2)

作者: lamsir 時間: 2024-7-7 18:19
本帖最後由 lamsir 於 2024-7-7 18:31 編輯
厲害
呢條公式比起我之前寫的簡潔高雅,我冇諗過唔用Array formula都可以解決此問題
此式最巧妙地方係
1) 通過 -LEFT(A2,ROW($1:$6)) 中的-將非數字的字串設為#VALUE錯誤值,返回一個6元素的負數及錯誤值陣列
2) 然後用 LOOKUP函數省略look_value技巧,找出返回陣列中最後一個非錯誤值,再通過LOOKUP前的-號令負數變回正數,從而確定數字有幾多個位
Ching真乃 Excel達人,佩服佩服
不過公式還有一個地方可修正如下:
- =LEFT(REPT("0",6-LEN(-LOOKUP(,-LEFT(A2,ROW(INDIRECT("1:6"))))))&A2&REPT(" ",30),30)
作者: ivanyung 時間: 2024-7-8 13:28
回覆 20# lamsir
最初是看到師兄在不使用VBA便能完成。所以便胆粗粗試下,我並不是師兄所說的那麼利害。
- =LEFT(REPT("0",6-SUMPRODUCT(1*ISNUMBER(--MID(A2,ROW($1:$6),1)),1*ISNUMBER(--LEFT(A2,ROW($1:$6)))))&A2&REPT(" ",30),30)
作者: sbg 時間: 2024-7-8 22:08
多謝ching另一個寫法
真係只要動腦筋就得
不過小弟真係才疏學淺
淨係識d最基本功能
依照ching方程要逐個功能去查下點用
作者: sbg 時間: 2024-7-8 22:10
再次多謝 lamsir ching
給我解釋 ivanyung ching的方程
使我理解得更深入


