2023年12月23日 星期六

以PYTHON執行,經由langchain代理程式介接,使用CHATOPEN AI服務

langchain代理程式介接功能,雷同 瀏覽器add-on外掛程式 或 EXCEL增益集功能概念

下面為PYTHON程式,經由langchain代理程式介接,使用CHATOPEN AI服務

from langchain.chat_models import ChatOpenAI

#llm = ChatOpenAI(openai_api_key="...  此處需將最前面註解#去除,並將您在CHATOPEN產的API金鑰值,貼在此處以便讓您有權存取使用AI服務")

# 大型語言模型LLM 參數匯入糸統
from langchain.llms import OpenAI

# LLM 參數,查詢參數精準度初始化調整
llm = OpenAI(temperature=0.7)

# 輸入您欲查詢之資訊
text = "請摘要說明Langchain Agent,可提供界接雲端服務有哪些 (如:wolfram、chatopenai、serpapi agent)? 請列舉幾個生活上實用範例"

# 經由LLM 及ChatOpenAI服務,將詢問結果產出
prediction = llm(text)
print(prediction.strip())


程式產出結果:  (等同在瀏覽器下 PROMPT提示資訊手動詢問AI:請摘要說明Langchain Agent,可提供界接雲端服務有哪些 (如:wolfram、chatopenai)? 請列舉幾個生活上實用範例)

Langchain Agent是一種人工智能平台,其主要功能是提供界接雲端服務。它可以幫助用戶快速接入各種雲端服務,提供更加便捷和高效的使用體驗。Langchain Agent可以提供的界接雲端服務包括:

1. Wolfram:Wolfram是一個強大的數據分析和計算平台,它可以幫助用戶解決各種數學和科學問題。Langchain Agent可以幫助用戶接入Wolfram,讓用戶可以直接在Agent的界面上進行數據分析和計算,無需打開瀏覽器或下載軟件。

2.ChatOpenAI:它是一個開放式人工智能平台,可以提供自然語言處理、對話式機器人、語言翻譯等功能,開發人員可以通過Langchain AI程式庫輕鬆與ChatOpenAI進行交互,從而實現智能對話機器人等應用。


後記:

一、使用CHATGPT服務需要存取使用權,故需取得API KEY,並貼在程式中 或 設定openai_api_key 變數值於電腦系統環境變數中。

二、匯入必要之函式庫 ,備妥執行環境,如: 

pip install langchain
三、如此PYTHON程式,就可自動化去運用AI功能,而不用瀏覽器去操作詢問了 

 



2023年12月22日 星期五

用PYTHON程式協助products sampling抽驗順位決策


情境:
商品抽驗順位決策參考,

希望依不同部門別,對其業管的商品進行抽樣檢查,
並優先對較久沒被 抽驗過之商品進行查驗,且如果累計抽查次數較多,則將抽驗順位向後調整,
依部門別,每次提供建議抽查之6樣商品


此種用法不限對抽驗商品名稱,亦可用在業務稽核用途;只要將,部門別 換做為總經理室、人事室、會計室 ,而商品名稱 換做 同仁姓名 ,可增加公平性

(抽驗商品資訊如下,有生鮮部、熟食部、及零食部,各自有抽驗過紀錄)

部門   商品名稱  抽查日     累計抽查次
生鮮部    海鮮    1121201       4
生鮮部    貢丸    1121102     2
生鮮部    甜不辣    1121002     1
生鮮部    凍豆腐    1120903     1
生鮮部    花枝丸    1120801        1
生鮮部    黑輪    1120703     1
生鮮部    海鮮    1120603        4
生鮮部    魚丸    1120503     1
生鮮部    海鮮    1121201     1
生鮮部    貢丸    1121102     1
生鮮部    甜不辣    1121002     1
生鮮部    凍豆腐    1120903     1
熟食部    羊肉串    1121201     1
熟食部    雞肉串    1121102     1
熟食部    肉包    1121002     2
熟食部    菜包    1120903     3
熟食部    炒飯    1120801     2
熟食部    炒麵    1120703     1
熟食部    雞塊    1120603        1
熟食部    肉包    1120603     2
熟食部    菜包    1120503       3
熟食部    烤玉米    1120401     4
零食部    花生    1121101     6
零食部    蜜餞    1121001     5



PROMPT提示訊息下法: (AI協助寫PYTHON程式)
針對D:\samplingLIST.csv,每列資料分別為部門別、 商品名稱、 抽檢日、累計抽驗數,
請以PYTHON程式, 協助分析提供下次優先抽驗商品名稱,
依部門別進行分類後,各自提供建議優先抽驗商品名稱,列出6商品,
請以 抽檢日為主要判斷,找出 商品名稱 最少被抽驗到的商品列為最優先抽驗,
以累計抽驗數為次要判斷,亦即次數較高者,則抽驗順位向後

最後,請將結果放置於 D:\samplingOUTPUT.TXT,分別為 每部門別及  分別列出6件建議優先抽驗商品名稱。

產出結果,如下:   (減少漏網出錯,並提昇工作效率)
熟食部
烤玉米
雞塊
炒麵
炒飯
雞肉串
羊肉串


生鮮部
魚丸
黑輪
花枝丸
凍豆腐
甜不辣
貢丸


零食部
蜜餞
花生 


import csv
#自D:\samplingLIST.csv 載入檔案,略過標題列
with open('D:/samplingLIST.csv', newline='', encoding='UTF-8') as csvfile:
    reader = csv.reader(csvfile)
    header = next(reader)  # 略過標題列
    data = [row for row in reader]

# 按部門、檢查日期和累计檢查次數,對資料進行排序
data.sort(key=lambda x: (x[0], x[2], int(x[3])))

# 對分類資料進行反覆運算,並跟蹤每樣產品的檢測次數
inspections = {}
for row in data:
    department = row[0]
    product = row[1]
    if department not in inspections:
        inspections[department] = {}
    if product not in inspections[department]:
        inspections[department][product] = {'inspection_count': 0, 'inspection_dates': set()}
    inspections[department][product]['inspection_count'] += 1
    inspections[department][product]['inspection_dates'].add(row[2])

# 每個部門,提供至少的六個優先檢查產品清單,產出結果到
samplingOUTPUT.TXT  
with open('D:/samplingOUTPUT.TXT', 'w', encoding='UTF-8') as outfile:
    for department in inspections:
        outfile.write(f"\n\n{department}\n")
        sorted_products = sorted(inspections[department], key=lambda x: (len(inspections[department][x]['inspection_dates']), inspections[department][x]['inspection_count']))
        for product in sorted_products[:6]:
            outfile.write(f"{product}\n")

 

後記:

一、一開始是用VBA程式,但TRY了近10次都出現RUNTIME ERROR,改用PYTHON程式,1次就處理完成也沒有BUG,只要抽驗歷史紀錄持續更新,今後哪個最久沒被抽驗商品,也就無所遁形了😏。

二、PYTHON程式要讀檔類型為UTF-8編碼,可透過NOTEPAD++之主選單  編碼(N) | 轉成UTF-8 | 存檔至 D:\samplingLIST.csv

2023年12月16日 星期六

EXCEL VBA常用參考資訊

EXCEL VBA運用框架關鍵資訊

應用程式(Application),Microsoft Excel 是一個應用程式,它可以打開並編輯工作簿,每個工作簿可以包含多個工作表。


工作簿(Workbook):Excel 文件的容器,可以包含多個工作表。一個工作簿可以包含多個工作表,並且可以進行保存、打開和編輯。

工作表(Worksheet):Excel 中的一個分頁,用於方便歸納分類和存儲數據用途頁籤。每個工作簿可以包含多個工作表。工作表包含由列和欄組成的單元格(小方格)。


儲存格(Cell):工作表中的一個方格,用於存儲數據。每個儲存格由列和行交叉形成,可以包含文本、數字、公式等。

 
列(Column):工作表中的垂直方向的一系列儲存格。每一列由字母表示,例如 A、B、C 等。


行(Row):工作表中的水平方向的一系列儲存格。每一行由數字表示,例如 1、2、3 等。

 
範圍(Range):工作表中的一個連續儲存格的集合。範圍可以是單個儲存格,也可以是多個相鄰儲存格的組合,它亦是指定套用公式之範圍 的設定小幫手。


參考範例 (將多個工作簿儲存後,並將它關閉工作簿儲存後,並將它關閉)
For Each wbs In Application.Workbooks
   wbs.Save
Next wbs
Application.Quit

Windows("活頁簿1").Activate          'EXCEL預設開啟,即為工作簿(或活頁簿)
    ActiveWindow.Close


參考範例
ActiveWorkbook.SaveAs "C:\Test.xls"

With Application.FileDialog(msoFileDialogFilePicker)
.InitialFileName = ThisWorkbook.Path & "\"
.Title = "開啟檔案對話窗格"

參考範例
Set ws1 = ThisWorkbook.Worksheets("工作表1")
lastRow1 = ws1.Cells(ws1.Rows.Count, 2).End(xlUp).Row  ' 左邊為列的計數;右邊數字2,代表B欄位,取得最後列的資料筆數,回傳給lastRow1變數


參考範例
Workbooks("Test.xls").Worksheets("工作表1").Range("A1").Value = 88

Range("A1").Select
ActiveCell.Value = 88  '目前儲存格A1,被選取的值,指定為88


執行外部程式(如:可執行預先寫好的Batch批次檔(OOO.bat)或讓EXCEL透過SHELL,直接執行PYTHON程式,如下面範例)

Shell "python c:\DoSomething.py", vbNormalFocus          'EXCEL去執行外部PYTHON應用程式



Application.DisplayAlerts = False
'控制 Excel 應用程式是否顯示警告訊息。
ActiveWindow.SelectedSheets.Delete
'設定刪除選定 頁籤時,不會有警告。


Application.ScreenUpdating = False
'控制 Excel 應用程式是否更新螢幕顯示。

Application.EnableEvents = True
'控制 Excel 應用程式,將會觸發各種事件,例如工作表的更改事件、工作簿的打開和關閉事件等。亦即,當您在 VBA 程式中設置了一個工作表的更改事件,該事件將會被觸發,並且相應的程式碼將被執行。 

Application.CutCopyMode = False
 '清除剪貼簿中的內容

     
Application.StatusBar = "正在更新資料..."
' 進行資料更新的程式碼,於下方狀態列,告知使用者EXCEL仍在更新資料


On Error Resume Next
'當程式碼執行遇到錯誤時,會忽略該錯誤並繼續執行下一行程式碼。

On Error GoTo Label01 
'當程式碼執行遇到錯誤時,會將控制權轉移到指定的錯誤處理程式碼 (Label01:)。




公式(Formula),自動貼在整A1到A100儲存格,貼上公式,省去拖拉之處理時間

Sub DuplicateFormulaFlag()
    Dim ws As Worksheet
    Dim rng As Range
    Dim cell As Range
    
    ' 設定要操作的工作表
    Set ws = ThisWorkbook.Worksheets("Sheet1") ' 修改為你的工作表名稱
    
    ' 設定要操作的範圍
    Set rng = ws.Range("A1:A100")
    
    ' 使用 For Each 迴圈逐一處理每個儲存格
    For Each cell In rng
        ' 將公式貼上儲存格
        cell.Formula = "=IF(COUNTIF(" & rng.Address & "," & cell.Address & ")>1,""重複"",""沒重複"")"
    Next cell
End Sub




檢查File是否存在函數
      Private Function FileExists(fname) As Boolean '判斷Excel檔是否存在
'   Returns TRUE if the file exists
        Dim x As String
        x = Dir(fname)
        If x <> "" Then FileExists = True _
        Else  FileExists = False
End Function


常用函數

VLOOKUP函數,是一個簡單的垂直查找所要查「特定字串值 」,並可回傳查找值在第一列中的匹配,對應相對位置之陣列值
(如:查找姓名,依其對應陣列中同列欄位位置資訊,如:身份證號;或可透過查此函數,與其它工作表之相對資訊,比對查看「特定字串值」,是否為在職人員等)。
INDEX與MATCH函數提供更靈活的查找和檢索功能,可以根據多個條件進行查找並返回更多的結果。





Excel表,第1列為標題列,請在工作表1 ,請協助用VBA程式,將所有 工作表1 中之空白列全數刪除,並以B欄做為判斷資料是否為空值


Sub DeleteActiveEmptyRows()   '刪除  作動中之工作表,所有空白列
    Dim ws As Worksheet
    Dim lastRow As Long
    Dim i As Long
    Dim sheetName As String
    sheetName = ActiveSheet.Name
    
    ' 取得作動中之  工作表
    Set ws = ThisWorkbook.Worksheets(sheetName)
      
    ' 取得最後一列的行數 (2代表,以B欄位做為研判資料筆數基準)
    lastRow = ws.Cells(ws.Rows.Count, 2).End(xlUp).Row
    
    ' 從最後一列往上檢查每一列的B欄是否為空值,如果是則刪除該列
    For i = lastRow To 2 Step -1
        If ws.Cells(i, 2).Value = "" Then
            ws.Rows(i).Delete
        End If
    Next i
End Sub


進階資訊:

EXCEL 可自行撰寫類別元件,檔案類型為.cls,經由模組(Module)中之巨集程式,將其呼叫執行
例如下面為AI,撰寫出64位元上網VBA CLASS元件,所以EXCEL執行如RS-232 數據通訊CLASS元件應該也不是難事
Private Declare PtrSafe Function InternetOpen Lib "wininet.dll" Alias "InternetOpenA" (ByVal Agent As String, ByVal AccessType As LongPtr, ByVal ProxyName As String, ByVal ProxyBypass As String, ByVal Flags As LongPtr) As LongPtr

Private Declare PtrSafe Function InternetConnect Lib "wininet.dll" Alias "InternetConnectA" (ByVal hInternetSession As LongPtr, ByVal ServerName As String, ByVal ServerPort As Integer, ByVal UserName As String, ByVal Password As String, ByVal Service As LongPtr, ByVal Flags As LongPtr, ByVal Context As LongPtr) As LongPtr
    

Private Declare PtrSafe Function InternetCloseHandle Lib "wininet.dll" (ByVal hInet As LongPtr) As Boolean
    

Private Declare PtrSafe Function InternetReadFile Lib "wininet.dll" (ByVal hConnect As LongPtr, ByVal Buffer As String, ByVal NumberOfBytesToRead As LongPtr, NumberOfBytesRead As LongPtr) As Boolean
    

Private Declare PtrSafe Function HttpOpenRequest Lib "wininet.dll" Alias "HttpOpenRequestA" (ByVal hHttpSession As LongPtr, ByVal Verb As String, ByVal ObjectName As String, ByVal Version As String, ByVal Referer As String, ByVal AcceptTypes As LongPtr, ByVal Flags As LongPtr, Context As LongPtr) As LongPtr


串列通訊傳輸元件

Private Declare PtrSafe Function BuildCommDCB Lib "kernel32" Alias "BuildCommDCBA" _
    (ByVal lpDef As String, lpDCB As DCB) As Long

    

PROMPT提示訊息下法: 

請寫VBA程式,運用上面元件(BuildCommDCBA),執行RS-232傳輸測試

PROMPT提示訊息下法:
用schtasks,建立排程,於每週,週一11:59,對磁碟機進行重組

schtasks /create /tn "Disk Defragmentation" /tr "defrag C:" /sc weekly /d MON /st 11:59:00 /f /ri 2

# 建立一個磁碟碎片整理的排程任務
# - `/create`: 建立新的排程任務
# - `/tn "Disk Defragmentation"`: 指定要建立的任務名稱為 "Disk Defragmentation"
# - `/tr "defrag C:"`: 指定任務執行的命令,這裡是以 `defrag` 命令針對 `C:` 磁碟進行碎片整理
# - `/sc weekly`: 指定任務的執行頻率為每週
# - `/d MON`: 指定任務執行的星期幾,這裡設定為星期一
# - `/st 11:59:00`: 指定任務的開始時間,這裡設定為上午 11:59:00
# - `/f`: 強制建立任務,即使已存在同名任務
# - `/ri 2`: 指定任務執行失敗時的重試次數,這裡設定為重試兩次


查看排程是排訂  工作名稱為「Disk Defragmentation」、檢視下次執行時間及其狀態
schtasks /query | more

微軟schtask查詢

系統最佳化參考資訊




EXCEL 樞鈕分析表 之應用,將財產細項 (公司 所有資訊設備細項型號產品)歸納,並依單位別的不同,計數其數量

 情境說明:

公司老闆詢問,所有資訊設備細項(即相同型號電腦相關產品,如:ASUS、iPad、印表機等),在每個部門中,各自有多少台裝置在使用,並分別放置於何處?

EXCEL欄位,分別如下:

財產編號    財產分類    財產細項     保管單位    存放地點 ,


1.插入  樞鈕分析表
2.新增 工作表 (EXCEL下方工作表旁 ,+圖示),方便處理顯示 樞鈕分析表
2.點選  右方 樞鈕分析表欄位 財產分類、財產細項、保管單位
3.下方區域之間 拖曳欄位  
        欄,拖曳   保管單位        <--  主要目的,是細分顯示,有多少台使用設備 財產細項
        
        列,拖曳   財產分類、財產細項、存放地點
        
        值,拖曳   財產細項


呈現樣式結果

                          總經理室      人事室      會計室      企劃部         
財產分類
    財產細項
        存放地點
        
電腦
    Apple iPad               1
        總經理辦公桌


文字檔有網頁開啟清單,用PYTHON程式,將網頁全數開啟,並找出特定字串,將其另存至文字檔中

情境說明:

PROMPT提示訊息下法:   (範例2) 

D:/HyperLinkSource.txt 此檔案內含連結位址,請用PYTHON寫程式,CHROME瀏覽器,開啟該文字檔案全數連結,並按任意鍵繼續瀏覽下個頁面


import webbrowser

# 读取文本文件中的链接
file_path = 'D:/HyperLinkSource.txt'

with open(file_path, 'r') as file:
    # 逐行读取链接
    for line in file:
        # 移除行尾的换行符
        url = line.strip()
        
        # 使用webbrowser模块打开链接
        webbrowser.open(url)
        
        # 等待用户按下任意键继续
        input("Press Enter to continue...")
         
 

 

PROMPT提示訊息下法:      (範例2) 

D:\HyperLinkSource.txt 此檔案內含連結位址,請用PYTHON寫一程式,運用requests與BeautifulSoup模組,以預設瀏覽器,開啟該文字檔案提供全數連結

,並請協助各自讀取每個連結之網頁內容後,將網頁內容中有包含  詳洽本公司: 開始 到  < 回訊息列表   間的字串值 將字串值取出至D:\BrowsingString.txt ,

該檔如存在請刪除,重新建檔,且該檔包含 該連結位址 及 網頁內容之特定字串,如找不到資料詳洽之特定字串,則用 找不到特定字串, 處理,並請接續處理下一筆連結之瀏覽檢視作業

import os
import requests
from bs4 import BeautifulSoup

# 讀取連結位址檔案
file_path = r'D:\HyperLinkSource.txt'
with open(file_path, 'r') as file:
    links = file.readlines()

# 刪除 output_file 若存在
output_file = r'D:\BrowsingString.txt'
if os.path.exists(output_file):
    os.remove(output_file)

# 開啟瀏覽器並處理每個連結
for link in links:
    link = link.strip()  # 移除連結前後的空白字符
    try:
        # 使用requests獲取網頁內容
        response = requests.get(link)
        response.raise_for_status()  # 確保獲取網頁成功
        webpage_content = response.text

        # 使用BeautifulSoup解析網頁內容
        soup = BeautifulSoup(webpage_content, 'html.parser')

        # 尋找特定字串值
        start_marker = '詳洽本公司:'
        end_marker = '< 回訊息列表'
        start_index = webpage_content.find(start_marker)
        end_index = webpage_content.find(end_marker)

        # 提取特定字串值
        if start_index != -1 and end_index != -1:
            substring = webpage_content[start_index + len(start_marker):end_index].strip()
        else:
            substring = '@@ 找不到特定字串'

        # 將特定字串值寫入檔案
        with open(output_file, 'a', encoding='utf-8') as file:
            file.write(f'{link}\n')
            file.write(f'{substring}\n\n\n')
    except requests.exceptions.RequestException as e:
        print(f'無法獲取連結:{link}')
        print(f'錯誤訊息:{e}')

後記:取出的網頁資訊,仍保留許多HTML語法資訊,故如要估資料再次運用,可能此方法不是最佳方式,只是測試PYTHON程式,捉取網頁內容特定2關鍵字,將其抽取出至另1個文字檔D:\BrowsingString.txt

EXCEL 同產品名稱 ,銷售金額 ,用VBA程式查詢


EXCEL表中,分別有訂單編號、訂購日期、產品名稱、單價、數量、小計等欄位,
想瞭解下表中  同一產品名稱 ,其銷售一共多少錢?


   A          B            C         D       E        F   
訂單編號    訂購日期    產品名稱    單價    數量    小計
A0001        112/5/1        鉛筆           20        6        120
A0002        112/6/6        原子筆        30        2        60
A0003        112/7/7        剪刀           46        2        92
A0004        112/6/8        美工刀        40        2        80
A0005        112/8/9        鉛筆           20        4        80
A0006        112/6/10     橡皮擦        15        2        30
A0007        112/9/9        精美提袋    80        3        240
A0008        112/9/12      原子筆        30        4        120
A0009        112/10/13    剪刀           46        2        92
A0010        112/11/15    鉛筆           20        2        40


藉由AI(ChatGPT)協助將同一產品名稱,歸納成同一群組後,彙總成單筆銷售數量。
PROMPT提示訊息下法:
EXCEL表中,有訂單編號、訂購日期、產品名稱、單價、數量、小計欄,請以EXCEL VBA程式,將相同 產品名稱 進行排序,歸納為同一群組,並將 相同產品名稱 彙集成1筆 單價及數量,
結果分別存放至    I2欄為產品名稱 J2欄為單價 K2欄為相同品項數量加總


Sub 彙集產品資料()
    Dim ws As Worksheet
    Dim lastRow As Long
    Dim i As Long
    Dim productName As String
    Dim price As Double
    Dim quantity As Long
    Dim summaryRow As Long

    ' 設定工作表,這裡假設資料在第一個工作表
    Set ws = ThisWorkbook.Sheets(1)

    ' 找到最後一行
    lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row

    ' 初始化目標列
    summaryRow = 2 ' 假設第一行是標題,從第二行開始

    ' 按照產品名稱進行排序
    ws.Sort.SortFields.Clear
    ws.Sort.SortFields.Add Key:=ws.Range("C2:C" & lastRow), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
    With ws.Sort
        .SetRange ws.Range("A1:F" & lastRow)
        .Header = xlYes ' 假設有標題行
        .MatchCase = False
        .Orientation = xlTopToBottom
        .SortMethod = xlPinYin
        .Apply
    End With

    ' 循環處理每一行資料
    For i = 2 To lastRow ' 假設第一行是標題,從第二行開始

        ' 取得產品名稱
        productName = ws.Cells(i, 3).Value ' 假設產品名稱在第3欄

        ' 取得單價和數量
        price = ws.Cells(i, 4).Value ' 假設單價在第4欄
        quantity = ws.Cells(i, 5).Value ' 假設數量在第5欄

        ' 如果是相同的產品名稱,則彙集數據
        If productName = ws.Cells(summaryRow, 9).Value Then
            ' 加總數量
            ws.Cells(summaryRow, 11).Value = ws.Cells(summaryRow, 11).Value + quantity
        Else
            ' 新的產品,將結果寫入新的一行
            summaryRow = summaryRow + 1
            ws.Cells(summaryRow, 9).Value = productName ' 產品名稱
            ws.Cells(summaryRow, 10).Value = price ' 單價
            ws.Cells(summaryRow, 11).Value = quantity ' 數量
        End If
    Next i

End Sub



請按照以下步驟使用此程式:
STEP1:開啟您的Excel檔案。
STEP2:按下Alt + F11進入VBA編輯器。
STEP3:在VBA編輯器中,插入一個新的模組Module。
STEP4:將上述VBA程式碼,複製並貼上到新的模組Module中。
STEP5:在VBA編輯器中,按下F5運行程式。


相關可運用AI工具輔助寫程式資源