2

我正在尝试创建一个数据透视表,然后是来自 ahk 的数据透视图,用于嵌入到电子邮件中。我是个菜鸟,所以请原谅我的代码质量。我无法正确设置数据透视表,并且无法在我的一生中出现图表。我在这篇文章的底部包含了对我一直在工作的帖子的引用,以及期望的最终结果。

我的数据是两列,有(可能没有)时间标题和警告我希望能够创建一个图表,显示随着时间的推移警告的数量和类型,从那里获取对象的句柄和将其放入 Outlook 电子邮件中,或者甚至只是复制粘贴对我有用。请告知如何完成这项工作,我想我已经很接近了。

编辑 我更新了下面的代码,得到了创建图表的点(我肯定草率),我唯一缺少的是在数据透视表的图例字段中添加“警告”,并将轴(类别)从“ time" 到 "hours" 这将按小时而不是单个时间戳对警告进行分组。如果我手动执行此操作,我似乎得到了我想要的结果。之后,我只想删除图表标题,然后将图表分配给要嵌入的对象,或者将其放到剪贴板上。

感谢您的任何帮助。

        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

自动热键点 com/board/topic/125719-com-excel-pivot-table

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

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

样本输入:

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

4

2 回答 2

1

两个可能的建议:

  1. 搜索您想要作为 VBA 函数执行的操作(更有可能获得良好的搜索结果以寻找 VBA 建议)
  2. 在 Excel 中记录一个执行您想要执行的操作的宏,然后查看生成的 VBA 代码。换句话说,在录制宏时制作图表并删除标题,然后看看它是否为您提供了任何好的代码。在某些情况下,这会起作用,在某些情况下则不会。

使用这些方法中的任何一种都有望让您确定需要将哪些代码或函数转换为脚本。

于 2016-11-29T17:22:36.380 回答
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
        }
于 2016-12-04T12:09:28.687 回答