Public Const DBname As String = "stock.accdb" '預設檔名stock.accdb Global Target As String, Stockid As String, Stockname As String, Use_Combo_Changeid As Boolean
Sub Manually()
Dim LastRow As Integer, online1 As Integer, online2 As Integer, Crange As Range, Combo_Select, idtemp As String
If Use_Combo_Changeid = False Then
LastRow = Sheets("常用股票").Range("a1").CurrentRegion.Rows.Count If LastRow > 1 Then Set Crange = Sheets("常用股票").Range("a1", Sheets("常用股票").Range("a1").End(xlDown)) Else Set Crange = Sheets("常用股票").Range("a1") End If
idtemp = UCase(InputBox("請輸入證券代號")) If idtemp = "" Then Exit Sub
If CheckStockId(idtemp) = True Then Stockid = idtemp Combo_Select = Application.Match(Stockid, Crange, 0) If IsError(Combo_Select) Then LastRow = LastRow + 1 Sheets("常用股票").Cells(LastRow, 1) = Stockid Combo_Select = LastRow - 1 Else Combo_Select = Combo_Select - 1 End If Else MsgBox "股票代號錯誤,請重新輸入", vbOKOnly, "Error" Exit Sub End If Call AddComboData(LastRow, Combo_Select)
End If
Use_Combo_Changeid = False
With Sheets("工作表1") .Columns("C:N").ClearContents
Call Get_Offline_Data
If .Cells(2, 3) = "*" And .Cells(2, 8) = "*" Then Debug.Print "all offline" Call Get_Offline_Stockname Else If .Cells(2, 3) = "" Then online1 = 1 Else online1 = 2 If .Cells(2, 8) = "" Then online2 = 2 Else online2 = 1 If online1 = 1 And online2 = 2 Then Debug.Print "all online" Else Debug.Print "1 online + 1 offline"
Call Get_Online_Data(online1, online2) 'save to access
End If End With
Call TypeSetting
End Sub
Sub Get_Offline_Data()
ttt = Timer If Stockid = "" Or Stockid = "股票代號" Then Exit Sub Dim DB As Object, RS As Object, lastday As String, day(1 To 2) As String, k As Integer, Rsql As String Set GetXml = CreateObject("WinHttp.WinHttpRequest.5.1") Set DB = CreateObject("ADODB.Connection") Set RS = CreateObject("ADODB.Recordset")
DB.Open "Provider=Microsoft.ACE.OLEDB.12.0; Data Source=" & Target & ";"
Application.ScreenUpdating = False
With Sheets("工作表1") day(1) = .ListBoxes("list_0").List(.ListBoxes("list_0")) day(2) = .ListBoxes("list_1").List(.ListBoxes("list_1"))
For k = 1 To 2 Rsql = "SELECT 序,持股,人數,股數,比例 from " & Stockid & " WHERE 日期='" & day(k) & "'" RS.Open Rsql, DB, 3, 3 Debug.Print RS.RecordCount If RS.RecordCount <> 0 Then .Cells(2, 3 + ((k - 1) * 5)) = "*" .Cells(4, 3 + ((k - 1) * 5)).CopyFromRecordset RS End If RS.Close Next k End With
With Sheets("工作表1") .Select .Cells(2, 4) = day(1) .Cells(2, 9) = day(2) End With
Sub Get_Online_Data(online1 As Integer, online2 As Integer) 'save to access
ttt = Timer
If Stockid = "" Or Stockid = "股票代號" Then Exit Sub
Dim HTMLsourcecode As Object, GetXml As Object, day(1 To 2) As String, DB As Object, sql As String, openDB As String, r As Integer, url_a As String, temp() As String, Combo_Select As Integer, Combo_Text As String Set HTMLsourcecode = CreateObject("htmlfile") Set GetXml = CreateObject("WinHttp.WinHttpRequest.5.1") Set DB = CreateObject("ADODB.Connection") openDB = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source=" & Target & ";" DB.Open openDB
For k = online1 To online2 r = 0 retry2: url_a = "scaDates=" & day(k) & "&scaDate=" & day(k) & "&SqlMethod=StockNo&StockNo=" & Stockid & "&radioStockNo=" & Stockid & "&StockName=&REQ_OPR=SELECT&clkStockNo=" & Stockid & "&clkStockName="
With GetXml .Open "POST", "https://www.tdcc.com.tw/smWeb/QryStockAjax.do", False .setRequestHeader "Content-Type", "application/x-www-form-urlencoded" .setRequestHeader "Referer", "http://www.tdcc.com.tw/smWeb/QryStock.jsp" .setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)" .send url_a
HTMLsourcecode.body.innerhtml = .responsetext
If InStr(HTMLsourcecode.body.innerhtml, "Your request timed out") > 0 Then Debug.Print "timeout" Delaytick (0.05) r = r + 1 If r > 10 Then MsgBox "請稍後再試", vbOKOnly, "Error" Exit Sub End If GoTo retry2 End If '20180828 更新,網頁表格換位置了,(7、8),改成(6、7) Stockname = Split(HTMLsourcecode.all.tags("table")(6).Rows(0).innertext, "資料日期")(0) Set Table = HTMLsourcecode.all.tags("table")(7).Rows
If Table(1).Cells(0).innertext = "無此資料" Then Delaytick (0.05) r = r + 1 If r > 10 Then MsgBox day(k) & "此日期無資料", vbOKOnly, "Error" If day(1) <> day(2) Then sql = "INSERT INTO " & Stockid & _ " (日期,序,持股) VALUES " & _ "('" & day(k) & "','" & "1" & "','" & "無此資料" & "')" DB.Execute sql End If GoTo getnextday End If GoTo retry2 End If
ReDim temp(1 To Table.Length - 1, Table(2).Cells.Length - 1)
With Sheets("工作表1")
For i = 1 To Table.Length - 1
For j = 0 To Table(i).Cells.Length - 1 temp(i, j) = Table(i).Cells(j).innertext Next j
RS.Close DB.Close Set RS = Nothing Set DB = Nothing
Debug.Print "checkstockid", Timer - ttt
End Function
Sub SetFormatCondition()
Dim Crange As Range, C1 As FormatCondition, C2 As FormatCondition Set Crange = Sheets("工作表1").Range("m4", Sheets("工作表1").Range("n4").End(xlDown)) Crange.FormatConditions.Delete Crange.Font.Bold = True Set C1 = Crange.FormatConditions.Add(xlCellValue, xlGreater, "=0") C1.Font.Color = vbRed Set C2 = Crange.FormatConditions.Add(xlCellValue, xlLess, "=0") C2.Font.Color = -11489280 Set Crange = Nothing
End Sub
Sub addlistbox()
ttt = Timer Dim DB As Object, RS As Object, lastday As String, list_0, list_1, Combo_0, temp() Set DB = CreateObject("ADODB.Connection") Set RS = CreateObject("ADODB.Recordset") On Error Resume Next
DB.Open "Provider=Microsoft.ACE.OLEDB.12.0; Data Source=" & Target & ";" RS.Open "select 日期 from 日期清單 order by 日期 desc", DB, 3, 3 temp = RS.getrows
With Sheets("工作表1") .Select .Shapes.Range(Array("List_0", "List_1", "Combo_0")).Delete .Cells.Clear
Set list_0 = .ListBoxes.Add(.Range("a3").Left + 1, .Range("a3").Top, 82, 400) Set list_1 = .ListBoxes.Add(.Range("b3").Left + 1, .Range("b3").Top, 82, 400) Set Combo_0 = .Shapes.AddFormControl(xlDropDown, .Range("a1").Left, .Range("a1").Top, 86, 15) With list_0 .Name = "list_0" list_0.List = temp() .Selected(2) = True .OnAction = "Listbox_Change" End With With list_1 .Name = "list_1" list_1.List = temp() .Selected(1) = True .OnAction = "Listbox_Change" End With
With Combo_0 .Name = "Combo_0" .ControlFormat.DropDownLines = 10 Sheets("常用股票").Range("a1") = "股票代號" Call AddComboData(0, 1) .OnAction = "Combo_0_Change" End With If Stockid = "" Then Stockid = .Shapes("combo_0").ControlFormat.List(1)
.Cells.Font.Size = "10" .Columns.AutoFit .Columns("A:B").ColumnWidth = 15 .Cells(1, 1).Select End With
Application.ScreenUpdating = True
Debug.Print "表單物件" & Sheets("工作表1").Shapes.Count, "default stockid=" & Stockid Erase temp RS.Close DB.Close Set RS = Nothing Set DB = Nothing
End Sub Sub Listbox_Change()
Dim LastRow As Integer LastRow = Sheets("常用股票").Range("a1").CurrentRegion.Rows.Count
If Stockid <> "股票代號" And LastRow > 1 Then Use_Combo_Changeid = True Call Manually End If
End Sub
Sub Combo_0_Change()
Dim Combo_Select As Integer, LastRow As Integer LastRow = Sheets("常用股票").Range("a1").CurrentRegion.Rows.Count
With Sheets("工作表1") Combo_Select = .Shapes("combo_0").ControlFormat.Value Stockid = .Shapes("combo_0").ControlFormat.List(Combo_Select) Debug.Print Stockid End With
If Stockid <> "股票代號" And LastRow > 1 Then Use_Combo_Changeid = True Call Manually End If End Sub
Sub AddComboData(LastRow As Integer, Combo_Select)
Dim Combo_Range As String
If LastRow = 0 Then LastRow = Sheets("常用股票").Range("a1").CurrentRegion.Rows.Count Combo_Range = "常用股票!$A$2:$A$" & LastRow End If If LastRow = 1 Then Combo_Range = "常用股票!$A$1:$A$" & LastRow End If If LastRow > 1 Then Combo_Range = "常用股票!$A$2:$A$" & LastRow End If
With Sheets("工作表1") .Shapes("combo_0").ControlFormat.ListFillRange = Combo_Range .Shapes("combo_0").ControlFormat.Value = Combo_Select End With
End Sub
Sub Update_TDCC_day()
ttt = Timer
Dim GetXml As Object, DB As Object, RS As Object, r As Integer, TDCC_day() As String, a As Integer, d As Integer Set GetXml = CreateObject("WinHttp.WinHttpRequest.5.1") Set DB = CreateObject("ADODB.Connection") Set RS = CreateObject("ADODB.Recordset") DB.Open "Provider=Microsoft.ACE.OLEDB.12.0; Data Source=" & Target & ";"
On Error Resume Next r = 0 retry1: With GetXml '20180818 修正網址 .Open "POST", "https://www.tdcc.com.tw/smWeb/QryStockAjax.do", False .setRequestHeader "Content-Type", "application/x-www-form-urlencoded" .setRequestHeader "Referer", "https://www.tdcc.com.tw/smWeb/QryStock.jsp" .setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)" .send "REQ_OPR=qrySelScaDates"
If InStr(.responsetext, "Your request timed out") > 0 Or .responsetext = "[]" Then Debug.Print "timeout" Delaytick (0.01) r = r + 1 If r > 10 Then MsgBox "日期無法更新,請稍後再試", vbOKOnly, "Error" Exit Sub End If GoTo retry1 End If
For i = 0 To UBound(TDCC_day) RS.Open "SELECT 日期 FROM 日期清單 WHERE 日期='" & TDCC_day(i) & "'", DB, 3, 3 If RS.RecordCount = 0 Then 'Debug.Print "新增日期", TDCC_day(i), RS.RecordCount DB.Execute = "INSERT INTO 日期清單 (日期) VALUES ('" & TDCC_day(i) & "')" a = a + 1 Else '"日期重覆" d = d + 1 End If RS.Close Next i
End With
DB.Close Set RS = Nothing Set DB = Nothing Set GetXml = Nothing
'=============================================================== 'access + sql 來分析資料可是很強悍的,在大量資料的整理上,不是excel能比的 '以下是一個簡單的sql語法範例,(需搭配我上傳的資料庫使用) '有興趣的另外建檔來練習,sql語法,請自行google Sub test() Dim DB As Object, RS As Object, lastday As String, Target As String
Set DB = CreateObject("ADODB.Connection") Set RS = CreateObject("ADODB.Recordset")