创建数据透视表和图表在Excel COM中为Autohotkey

时间:2016-11-27 12:24:42

标签: excel vba com autohotkey pivot-chart

我正在尝试创建一个数据透视表,然后创建一个来自ahk的数据透视表,用于嵌入到电子邮件中。我是一个总菜鸟,所以请原谅我的代码质量。我无法将我的数据透视表设置正确,并且无法在我的生活中显示图表。我已经提到了我一直在做什么帖子的引用,以及本帖子底部所需的最终结果。

我的数据是两列,有(可能没有)时间标题,而警告我希望能够创建一个图表来显示数量,以及随时间推移的警告类型,从那里得到一个句柄对象并将其放入outlook电子邮件中,甚至只是复制粘贴对我有用。请告知如何完成这项工作,我认为我非常接近。

修改 我更新了下面的代码,得到了图表创建的重点(马虎im肯定),我唯一缺少的是向数据透视表中的图例字段添加“警告”,并从“时间”更改轴(catagories) “到”小时“这将按小时分组警告,而不是单独的时间戳。如果我手动这样做,我似乎得到了我想要的结果。之后,我只想删除图表标题,然后将图表分配给要嵌入的对象,或将其放到剪贴板上。

感谢您的帮助。

        f1::Reload
Pause::Pause
f2::ListVars
Pause
!`::
function()
return

function()
{

when:=[]
what:=[]
Nothing:="Nothing to report, have a wonderful day."
TMP:=""
RMRKS:=""
Date1:=""
Date2:=""
EMOUT:=""

EMIN := Clipboard                                       ; Email text var
Loop, Parse, EMIN,`n,`r                             ; parse email by line
{
tmp := StrSplit(A_LoopField, ";")           ; for each line break it into chunks by ";" 
rmrks := tmp.6                                  ; Warn code is in 6th index     
If (InStr(rmrks, "Warning"))                    ; If this is a warning line
{
date1:=StrSplit(tmp.1, "/")                 ; date/time is in DD/MM/YYYY , split it up by "/"
date2= % date1.2 "/" date1.1 "/" date1.3    ;  Rearrange the date into MM/DD/YYYY   
EMOUT .= date2 "`t" rmrks "`n"              ; Push into VAR "11/24/2016 13:40:45    WARNING MESSAGE"
}                                           

}
EMOUT := StrReplace(EMOUT,"""") ; Replace all of the quotes in the var with Null

Loop, Parse, EMOUT,`n,`r    ; Split output by line and then...
{           
tmp := StrSplit(A_LoopField, ["`t"])   ; split lines by tab
when.insert(tmp.1)                  ; insert date/time stamp into "when" array
what.insert(tmp.2)                  ; insert Warn Code into "what" array
}

if (emout!="")                                  ; If there was stuff to put into array
{
XL := ComObjCreate("Excel.Application")    ; create an excel object
wbk := xl.Workbooks.Add                          ; add a workbook to the object
Xl.Visible := True                         ; make it visible
XL.Range("A1").Value := "Time"             ;Create Time header
XL.Range("A:A").columnwidth := "20" 
XL.Range("B:B").columnwidth := "56.86"
XL.Range("B1").Value := "Warning"          ; Create Warning Header
for index in when       
        Xl.Range("A" . index+1).Value := when[index]   ;add everything in the "when" array
for index in what 
        Xl.Range("B" . index+1).Value := what[index]   ;add everything in the "what" array          




rng := xl.Sheets(1).UsedRange.address
trgt := xl.Sheets(1).range("c1")
pvt := xl.ActiveWorkbook.PivotCaches.Create(xlDatabase:=1, rng, xlPivotTableVersion12:=3).CreatePivotTable(trgt, "PivotTable1", ,xlPivotTableVersion12:=3)
pvt.PivotFields("warning").Orientation := 1
pvt.PivotFields("warning").Position := 1                
pvt.PivotFields("time").Orientation := 1
pvt.PivotFields("time").Position := 2           
pvt.AddDataField(pvt.PivotFields("Warning"), "Count of Warning",  -4112)    



Sheet := xl.Sheets(1)
Sheet.Shapes.AddChart.Select
wbk.ShowPivotChartActiveFields := false
xl.ActiveChart.ChartType := 51
xl.ActiveChart.PivotLayout.PivotTable.PivotFields("Warning").Orientation = xlColumnField
xl.ActiveChart.PivotLayout.PivotTable.PivotFields("Warning").Position = 1







return




}
if (emout="")
Msgbox, %Nothing%

Reload
}

我工作的来源论坛帖子是

autohotkey dot com / board / topic / 149544-table-pivot-vs-table-pivot-chart-com

autohotkey dot com / board / topic / 125719-com-excel-pivot-table

最终结果我正在寻找嵌入Outlook电子邮件:

http://imgur.com/a/6baLe

示例输入:

http://p.ahkscript.org/?p=a0ceb3b1

2 个答案:

答案 0 :(得分:1)

两个可能的建议:

  1. 搜索您尝试做的VBA功能(更有可能获得寻找VBA建议的好搜索结果)
  2. 记录一个宏,在Excel中执行您想要执行的操作,然后查看生成的VBA代码。换句话说,在记录宏时制作图表并删除标题,然后查看它是否为您提供了任何好的代码。在某些情况下,这将起作用,在某些情况下它不会。
  3. 使用这些方法中的任何一种都可以帮助您确定需要将哪些代码或函数转换为脚本。

答案 1 :(得分:0)

https://xkcd.com/979/

    f1::Reload
    Pause::Pause
    f2::ListVars
    Pause


    !`::

    SetKeyDelay, -1 




    Recipients:="test64413@gmail.com"

    TMP:=""
    RMRKS:=""
    Date1:=""
    Date2:=""
    City:=""
    Chart:=""
    Warnings:=""


    EMAIL:=clipboard   
    city:=Getcity(EMAIL)  ; Get city name
    Warnings := ParseWarnings(Email)


        if Warnings.MinIndex()                              ; If there was stuff to put into array
        {
            Chart := CreateChart(Warnings)
            CreateEmail(Chart, city,Warnings)
        }


        else
            msgbox , No Warnings





    ;###################################################################################################################################################################################################################;
    ;##########################################################################################      Functions      ####################################################################################################; 
    ;###################################################################################################################################################################################################################;


    ParseWarnings(Email)
    {
        Warnings := []
        EMAIL := StrReplace(EMAIL, """")                 ; Email text var. Remove all quotes.
        Loop, Parse, EMAIL, `n, `r                           ; Parse email by line
        {
            tmp := StrSplit(A_LoopField, ";")               ; For each line break it into chunks by ";" 
            rmrks := tmp.6                                  ; Warn code is in 6th index     
            If InStr(rmrks, "Warning")                      ; If this is a warning line
            {
                date1:=StrSplit(tmp.1, "/")                 ; Date/time is in DD/MM/YYYY , split it up by "/"
                Warnings.Push( {"When": date1.2 "/" date1.1 "/" date1.3, "What": rmrks} )  ;Warnings[1].when  //// Warnings[1].what
            }
        }
        return Warnings
    }

    CreateChart(Warnings)
    {
        static xlColumnClustered := 51
             , xlColumnField := 2
             , xlCount := -4112
             , xlDatabase := 1
             , xlHidden := 0
             , xlPivotTableVersion12 := 3
             , xlRowField := 1

        XL := ComObjCreate("Excel.Application")         ; Create an excel object
        Wbk := XL.Workbooks.Add                         ; Add a workbook to the object
        Xl.Visible := True                              ; Make it visible
        Sheet := xl.Sheets(1)                           ; Save a reference to this sheet

        ; Set Column headings and width
        Sheet.Range("A1").Value := "Time"               ; Create Time header
        Sheet.Range("A:A").columnwidth := "20" 
        Sheet.Range("B1").Value := "Warning"            ; Create Warning Header
        Sheet.Range("B:B").columnwidth := "56.86"

        ; Create a safe array and copy data into it. Then put the safe array into a range.
        nRows := Warnings.MaxIndex()                    ; The number of rows
        SafeArray := ComObjArray(12, nRows, 2)          ; Create a safearray of the correct size. (Type = 12, Rows = nRows, Columns = 2)
        for i, Warning in Warnings
        {
            SafeArray[i - 1, 0] := Warning.When         ; SafeArray[RowNumber, ColumnNumber] := Value
            SafeArray[i - 1, 1] := Warning.What         ; SafeArray index starts at 0 (not 1)
        }
        Cell := Sheet.Range("A2")                       ; The top left cell of the range
        Sheet.Range(Cell, Cell.Offset(nRows - 1, 1)).Value := SafeArray  ; Put the SafeArray into the Range

        rng := Sheet.UsedRange.address
        trgt := Sheet.range("c1")
        pvt := xl.ActiveWorkbook.PivotCaches
            .Create(xlDatabase, rng, xlPivotTableVersion12)
            .CreatePivotTable(trgt, "PivotTable1",, xlPivotTableVersion12)

        pfWarning := pvt.PivotFields("warning")
            pfWarning.Orientation := xlColumnField
            pfWarning.Position := 1
            pvt.AddDataField(pfWarning, "Count of Warning",  xlCount)






        ; **Is it necessary to set 'pfTime.Orientation' multiple times?
        pfTime := pvt.PivotFields("time")       ; VBA = With ActiveChart.PivotLayout.PivotTable.PivotFields("Time")
            pfTime.Orientation := xlHidden      ; VBA = ActiveChart.PivotLayout.PivotTable.PivotFields("Time").Orientation = xlHidden
            pfTime.Orientation := xlRowField    ; VBA = .Orientation = xlRowField
            pfTime.Position := 1                ; VBA = .Position = 1
            pfTime.AutoGroup                    ; Must be Office version >= 2016
        pvt.PivotFields("Minutes").Orientation := xlHidden  ; ???
            pfTime.Orientation := xlHidden      ; ???

        Sheet.Shapes.AddChart
        wbk.ShowPivotChartActiveFields := false

        Sheet.ChartObjects(1).Activate
        Chart := wbk.ActiveChart
            Chart.ChartTitle.Delete
            Chart.ChartType := xlColumnClustered
          Chart.PivotLayout.PivotTable.PivotFields("Warning").Orientation := xlColumnField
           Chart.PivotLayout.PivotTable.PivotFields("Warning").Position := 1

        return Chart
    }
    CreateEmail(Chart, city,warnings)
    {
        ; Reference: http://stackoverflow.com/questions/25603864/copy-excel-chart-to-outlook-mail-message
        ; Alternative method: http://www.mrexcel.com/forum/excel-questions/562877-paste-chart-into-email-body.html
        static olMailItem := 0

        olApp := ComObjCreate("Outlook.Application")
        Email := olApp.CreateItem(olMailItem)
        Email.Display
        Email.To := "test64413@gmail.com"
        Email.Subject := "*** Todays Warnings for Your Gain Site in " city " ***"
        body:=warndata(warnings)
        header:="`n" "`n" "Data:" "`n" 
        Email.body := header . body  
        Chart.ChartArea.Copy    
        wEditor := olApp.ActiveInspector.WordEditor
        wEditor.Application.Selection.Paste

    }
    GetCity(EMAIL)
    {
            Split := StrSplit(EMAIL, "`n", "`r") 
            City := Split[Split.Length()-5] 
        IfNotInString, City, ,
            City := Split[Split.Length()-6] 
            City:=strsplit(city,",")
            City:=City.1
            Return City
        }

        warndata(warnings) 
        {       
            for i, Warning in Warnings  
              body .= "`n" Warning.When "`t" Warning.What "`n"    ; This is not right
        return body
        }