2024年6月8日 星期六

用GPT修改M語法_以日期列處理

在2023年GPT開始使用時我就詢問過GPT,可能當時的GPT還不夠聰明,給予的答案無法運行,我認為原始的語法應該可以更聰明點,詢問過Power BI社群的人,但沒有人提供答案,終於在現在再度詢問GPT給予的答案與我思考的方向依樣,只是我懂得語法不多,透過GPT幫忙解答,我也學到了新知識。





下面是GPT提供目前最優的版本

let

    // 定义日期和参数

    起始日期 = "2023/12/29",

    最新日期 = "2024/6/7",

    周前日期 = "2024/5/31",

    日期列表 = {"2023/12/29", "2024/5/10", "2024/5/17", "2024/5/24", "2024/5/31", "2024/6/7"},

    趴數 = 0.05, // 例如5%

 

    // 数据处理

    來源 = Table.NestedJoin(投資組合, {"持股標的"}, 資料_5, {"標的"}, "資料_5", JoinKind.RightOuter),

    已展開資料 = Table.ExpandTableColumn(來源, "資料_5", List.Combine({{"標的"}, 日期列表})),

    已排序資料列 = Table.Sort(已展開資料, {{"持股標的", Order.Descending}}),

    已移除資料行 = Table.RemoveColumns(已排序資料列, {"持股標的"}),

    加入淨值 = Table.AddColumn(已移除資料行, "淨值", each [股數] * [匯率] * Record.Field(_, 最新日期)),

    Base_淨值總額 = List.Sum(加入淨值[淨值]),

    加入年度漲幅 = Table.AddColumn(加入淨值, "年度漲幅", each (Record.Field(_, 最新日期) - Record.Field(_, 起始日期)) / Record.Field(_, 起始日期), Percentage.Type),

    加入周漲幅 = Table.AddColumn(加入年度漲幅, "周漲幅", each (Record.Field(_, 最新日期) - Record.Field(_, 周前日期)) / Record.Field(_, 周前日期), Percentage.Type),

    加入淨值比 = Table.AddColumn(加入周漲幅, "淨值比", each [淨值] / Base_淨值總額, Percentage.Type),

    移除多餘列 = Table.RemoveColumns(加入淨值比, {"股數", "匯率", "淨值"}),

    重新排列列 = Table.ReorderColumns(移除多餘列, List.Combine({{"標的", "淨值比"}, 日期列表, {"周漲幅", "年度漲幅"}})),

    排序及篩選 = Table.SelectRows(

        Table.Sort(重新排列列, {{"淨值比", Order.Descending}, {"標的", Order.Descending}}),

        each (List.Contains(投資組合[持股標的], [標的]) or Number.Abs([周漲幅]) >= 趴數 or List.Contains(指數, [標的])) and not List.Contains(排除, [標的])

    )

in

    排序及篩選


下面是GPT提供減少手動版本

我只是將語法丟出,GPT自動提供簡易減少手動版本

let

    來源 = Table.NestedJoin(投資組合, {"持股標的"}, 資料_5, {"標的"}, "資料_5", JoinKind.RightOuter),

    #"已展開 資料_5____" = Table.ExpandTableColumn(來源, "資料_5", {"標的","2023/12/29","2024/5/10","2024/5/17", "2024/5/24","2024/5/31","2024/6/7"}),

    已排序資料列 = Table.Sort(#"已展開 資料_5____",{{"持股標的", Order.Descending}}),

    已移除資料行 = Table.RemoveColumns(已排序資料列,{"持股標的"}),

 

    // 獲取所有日期欄位名稱

    日期欄位名稱 = List.RemoveFirstN(List.RemoveItems(Table.ColumnNames(已移除資料行), {"標的", "股數", "匯率"}), 0),

    最後一欄 = List.LastN(日期欄位名稱, 1){0},

    最後第二欄 = List.LastN(日期欄位名稱, 2){0},

   

    // 計算淨值

    T淨值_______ = Table.AddColumn(已移除資料行, "淨值", each [股數]*[匯率]*Record.Field(_, 最後一欄)),

    Base_淨值總額 = List.Sum(T淨值_______[淨值]),

 

    // 計算年度漲幅和周漲幅

    T年度漲幅_____ = Table.TransformColumnTypes(

        Table.AddColumn(T淨值_______, "年度漲幅", each (Record.Field(_, 最後一欄) - Record.Field(_, "2023/12/29")) / Record.Field(_, "2023/12/29")),

        {{"年度漲幅", Percentage.Type}}

    ),

    T周漲幅_____ = Table.TransformColumnTypes(

        Table.AddColumn(T年度漲幅_____, "周漲幅", each (Record.Field(_, 最後一欄) - Record.Field(_, 最後第二欄)) / Record.Field(_, 最後第二欄)),

        {{"周漲幅", Percentage.Type}}

    ),

   

    // 計算淨值比

    T淨值比 = Table.TransformColumnTypes(

        Table.AddColumn(T周漲幅_____, "淨值比", each [淨值] / Base_淨值總額),

        {{"淨值比", Percentage.Type}}

    ),

   

    // 移除不必要的欄位

    已移除資料行1 = Table.RemoveColumns(T淨值比, {"股數", "匯率", "淨值"}),

 

    // 重新排列欄位順序

    重新排_____ = Table.ReorderColumns(已移除資料行1, {"標的", "淨值比"} & 日期欄位名稱 & {"周漲幅", "年度漲幅"}),

 

    // 排序及篩選資料

    T排序及篩選 = Table.SelectRows(

        Table.Sort(重新排_____, {{"淨值比", Order.Descending}, {"標的", Order.Descending}}),

        each (List.Contains(投資組合[持股標的], [標的]) = true or Number.Abs([周漲幅]) >= 趴數 or List.Contains(指數, [標的]) = true) and List.Contains(排除, [標的]) = false

    ),

  

in

    T排序及篩選


修改前的版本

let

    來源 = Table.NestedJoin(投資組合, {"持股標的"}, 資料_5, {"標的"}, "資料_5", JoinKind.RightOuter),

    #"已展開 資料_5____" = Table.ExpandTableColumn(來源, "資料_5", {"標的","2023/12/29","2024/5/10","2024/5/17", "2024/5/24","2024/5/31","2024/6/7"}),

    已排序資料列 = Table.Sort(#"已展開 資料_5____",{{"持股標的", Order.Descending}}),

    已移除資料行 = Table.RemoveColumns(已排序資料列,{"持股標的"}),

    T淨值_______ = Table.AddColumn(已移除資料行, "淨值", each [股數]*[匯率]*[#"2024/6/7"]), //這裡也要修改........

    Base_淨值總額 = List.Sum(T淨值_______[淨值]),

    T年度漲幅_____ = Table.TransformColumnTypes(

                 Table.AddColumn(T淨值_______, "年度漲幅", each ([#"2024/6/7"]-[#"2023/12/29"])/[#"2023/12/29"]) , //年度如果修改要去改 資料_5週那個進階查詢

                         {{"年度漲幅", Percentage.Type}}),

    T周漲幅_____ = Table.TransformColumnTypes(

                 Table.AddColumn(T年度漲幅_____, "周漲幅", each ([#"2024/6/7"]-[#"2024/5/31"])/[#"2024/5/31"]) ,  //這裡也要改

                       {{"周漲幅", Percentage.Type}}),

    T淨值比 = Table.TransformColumnTypes(Table.AddColumn(T周漲幅_____, "淨值比", each [淨值]/Base_淨值總額),{{"淨值比", Percentage.Type}}),

    已移除資料行1 = Table.RemoveColumns(T淨值比,{"股數", "匯率","淨值"}),

    重新排_____ = Table.ReorderColumns(已移除資料行1,{"標的", "淨值比","2023/12/29","2024/5/10","2024/5/17", "2024/5/24","2024/5/31","2024/6/7","周漲幅", "年度漲幅"}),

    T排序及篩選 = Table.SelectRows(

                    Table.Sort(重新排_____,{{"淨值比", Order.Descending}, {"標的", Order.Descending}}) , each (List.Contains(投資組合[持股標的],[標的])=true or Number.Abs([周漲幅])>=趴數 or List.Contains(指數,[標的])=true) and List.Contains(排除,[標的])=false   )

in

T排序及篩選

 



2024年6月2日 星期日

用VBA針對相片及影片以日期重分類

 

針對資料夾內所有子資料夾所有照片及影片檔案都移到最上層資料夾用VBA寫一個針對相片及影片的建立日、修改日、存取日判斷,以這三個日期中最小的日期依年月資料夾分類,如果該資料夾不存在就新建,當檔案名稱如果重複時就自動在檔案名稱依序給予 _+流水號


分類結果4436個影片及照片自動移到最上層資料夾,只花不到1分鐘

分類結果
分類結果

同一時間處理完畢
同一時間處理完畢



Sub OrganizePhotosAndVideosByDate()

    Dim topFolderPath As String

    Dim fso As Object

    Dim topFolder As Object

    Dim subFolder As Object

    Dim file As Object

    Dim earliestDate As Date

    Dim yearMonth As String

    Dim targetFolder As String

    Dim fileExtensions As Variant

    Dim i As Integer

    Dim fileName As String

    Dim newFileName As String

    Dim counter As Integer


    ' 設置要處理的頂層資料夾路徑

    topFolderPath = "C:\Your\Path\To\PhotosAndVideos" ' 替換為實際的路徑

    

    ' 要處理的文件副檔名

    fileExtensions = Array("jpg", "jpeg", "png", "gif", "bmp", "mp4", "avi", "mov", "wmv", "mkv")

    

    ' 創建 FileSystemObject

    Set fso = CreateObject("Scripting.FileSystemObject")

    Set topFolder = fso.GetFolder(topFolderPath)

    

    ' 遍歷頂層資料夾及其所有子資料夾中的每個檔

    Call ProcessFolder(topFolder, fso, topFolderPath, fileExtensions)

    

    MsgBox "Files have been organized by date.", vbInformation

End Sub


Sub ProcessFolder(folder As Object, fso As Object, topFolderPath As String, fileExtensions As Variant)

    Dim file As Object

    Dim subFolder As Object

    Dim earliestDate As Date

    Dim yearMonth As String

    Dim targetFolder As String

    Dim fileName As String

    Dim newFileName As String

    Dim counter As Integer


    ' 遍歷資料夾中的每個檔

    For Each file In folder.Files

        ' 檢查檔副檔名是否在目標副檔名清單中

        If IsInArray(LCase(fso.GetExtensionName(file.Path)), fileExtensions) Then

            ' 獲取檔的創建日期、修改日期和訪問日期

            earliestDate = GetEarliestDate(file.DateCreated, file.DateLastModified, file.DateLastAccessed)

            

            ' 格式化為 "YYYY-MM" 格式

            yearMonth = Format(earliestDate, "YYYY-MM")

            

            ' 設置目的檔案夾路徑

            targetFolder = topFolderPath & "\" & yearMonth

            

            ' 如果目的檔案夾不存在,則創建新資料夾

            If Not fso.FolderExists(targetFolder) Then

                fso.CreateFolder(targetFolder)

            End If

            

            ' 設置初始檔案名

            fileName = fso.GetBaseName(file.Name) & "." & fso.GetExtensionName(file.Name)

            newFileName = fileName

            counter = 1

            

            ' 如果目的檔案夾中已存在同名檔,則添加序號

            Do While fso.FileExists(targetFolder & "\" & newFileName)

                newFileName = fso.GetBaseName(file.Name) & "_" & counter & "." & fso.GetExtensionName(file.Name)

                counter = counter + 1

            Loop

            

            ' 移動文件到目的檔案夾

            file.Move targetFolder & "\" & newFileName

        End If

    Next file

    

    ' 遞迴處理子資料夾

    For Each subFolder In folder.SubFolders

        Call ProcessFolder(subFolder, fso, topFolderPath, fileExtensions)

    Next subFolder

End Sub


' 函數:檢查陣列中是否包含指定值

Function IsInArray(value As Variant, arr As Variant) As Boolean

    Dim element As Variant

    IsInArray = False

    For Each element In arr

        If element = value Then

            IsInArray = True

            Exit Function

        End If

    Next element

End Function


' 函數:獲取最早的日期

Function GetEarliestDate(date1 As Date, date2 As Date, date3 As Date) As Date

    GetEarliestDate = Application.WorksheetFunction.Min(date1, date2, date3)

End Function

代碼說明:


頂層資料夾路徑和檔副檔名:topFolderPath 變數指定要處理的頂層資料夾路徑,請將其替換為實際的路徑。fileExtensions 陣列包含要處理的檔案類型副檔名。


遍歷資料夾和文件:ProcessFolder 副程式遞迴遍歷指定資料夾及其所有子資料夾中的每個檔,並調用 IsInArray 函數檢查檔副檔名是否在目標副檔名清單中。


日期比較和分類:對於每個檔,獲取其創建日期、修改日期和訪問日期,並計算最早的日期。然後按 YYYY-MM 格式分類到對應的資料夾中。如果目的檔案夾不存在,則創建新的資料夾。


處理檔案名衝突:如果目的檔案夾中已存在同名檔,則添加序號以避免檔案名衝突。


輔助函數:IsInArray 函數用於檢查檔副檔名是否在目標副檔名清單中,GetEarliestDate 函數用於獲取三個日期中的最早日期。


運行此宏後,指定頂層資料夾及其所有子資料夾中的所有照片和視頻檔將移到最上層資料夾,並按最早日期的年月分類到對應的資料夾中。如果檔案名重複,將自動在檔案名後添加序號。


用GPT修改M語法_以日期列處理

在2023年GPT開始使用時我就詢問過GPT,可能當時的GPT還不夠聰明,給予的答案無法運行,我認為原始的語法應該可以更聰明點,詢問過Power BI社群的人,但沒有人提供答案,終於在現在再度詢問GPT給予的答案與我思考的方向依樣,只是我懂得語法不多,透過GPT幫忙解答,我也學到...