【问题标题】:Migrating Powerpoint information to Access database using VBA使用 VBA 将 Powerpoint 信息迁移到 Access 数据库
【发布时间】:2017-12-31 14:30:03
【问题描述】:

我在一家以 PowerPoint 形式存储大量源数据的大公司实习。这些 PowerPpoint 在跨部门和供应商之间进行沟通时效果很好,但正如您可能猜到的那样,它们缺乏任何可靠的分析。因此,我决定将这些 Powerpoints 数据库化到 Access 中。

据我所知,没有直接的方法可以做到这一点。由于严格的 IT 政策,我仅限于使用 VBA 作为我的编码平台。上周我已经编写了一个宏来解决我的问题。同样,由于没有将 PowerPoint 直接转换为 Access,我不得不以相当低效的方式解决这个问题,因为有一些警告。我将在下面列出我的步骤和注意事项。

  1. 我想要数据库的 powerpoint 信息被格式化为表格而不是文本。我一直无法找到将 PPT 表格直接转换为 Excel 或 CSV 文件的宏。因此,我会将所有 PPT 文件(大约 3000 个)转换为 PDF。

  2. 从这些生成的 PDF 中,我可以使用 Adob​​e 将它们转换为 Excel 或 CSV 文件。

  3. 使用多个在线资源和一些我自己的经验,我编写了一个 VBA 脚本,它会自动将 CSV 文件的文件夹格式化为 Access 可以正确存储的格式。参见代码 1。

    • (“Personal.xlsb!Module1.FormatAccess”是一个主要使用“记录宏”创建的宏。由于它的长度和冗余,我省略了此代码。)
  4. 格式化 CSV 后,我会将它们全部自动化到 Access。

  5. 在 Access 自动化之后,我需要将每个 PPT 文件嵌入到其各自的 Access 条目中

同样,这不是一个有效的过程。因为我仅限于 Microsoft 应用程序,所以我选择了这条路线。我曾考虑将信息保留为 Excel 文件,但其想法是让任何部门都可以访问和搜索这些数据,因此我选择 Access 来对它们进行数据库化。

现在我已经向您解释了我来自哪里以及我在做什么,我问:您对我有什么建议?我觉得我的迂回方式是一个很好的解决方案,也很实用,但我想知道是否有更好的解决方案。

代码 1

Sub LoopCSVFile()

Dim fso As Object  'Scritping.FileSystemObject
Dim fldr As Object 'Scripting.Folder
Dim file As Object 'Scripting.File
Dim wb As Workbook

Set fso = CreateObject("Scripting.FileSystemObject")
Set fldr = fso.GetFolder("C:\Users\HMM105289\Documents\Powerpoint Parsing\Test Folder\Test Save Folder")

For Each file In fldr.Files

    Set wb = Workbooks.Open(file.Path)

    Application.Run "Personal.xlsb!Module1.FormatAccess"

    wb.Close SaveChanges = True

Next

Set file = Nothing
Set fldr = Nothing
Set fso = Nothing

结束子

编辑 1

在尝试了 Tim 的一些建议后,我想出了这段代码来对每张 PPT 幻灯片进行检查。这个想法是让它在里面运行他的“ExtractTable”宏。就目前而言,我无法让它执行。

Sub PPTableXtraction()

Dim oSlide As Slide
Dim oSlides As Slides
Dim oPPT As Object: Set oPPT = ActivePresentation
Dim oShapes As Shape
Dim oTable As Object



For Each oSlide In oPPT.Slides
    For Each oShapes In oSlide.Shapes
        If oShapes.HasTable Then
            Application.Run "VBAProject.xlsb!Module3.ExtractTableContent"
        End If
    Next
Next


End Sub

编辑 2

我能够在 Tim 的代码的基础上创建一个循环每个 PowerPoint 文件并将信息提取到 Excel 中的代码。该代码不会闯入调试器,但无论出于何种原因,它都没有执行任何功能。有人知道为什么吗?

Sub Tester()
Dim ppts As PowerPoint.Application

Dim FolderPath As String
Dim FileName As String

FolderPath = "FolderPath"
FileName = Dir(FolderPath & "*.ppt*")

Do While FileName <> ""
    Set ppts = New PowerPoint.Application
    ppts.Visible = True
    ppts.Presentations.Open FileName:=FolderPath & FileName
    A = Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row + 5
    B = "B" & A
    X = "A" & A
    Range(X).Value = "New"

Dim ppt As Object, tbl As Object
Dim slide As Object, pres As Object, shp
Dim rngDest As Range


    Set ppt = GetObject(, "Powerpoint.Application")

    Set pres = ppt.ActivePresentation

    Set rngDest = Sheets("Data").Range(B) '

    For Each slide In pres.Slides
        For Each shp In slide.Shapes
            If shp.HasTable Then
                ExtractTableContent shp.Table, rngDest
                Set rngDest = rngDest.Offset(shp.Table.Rows.Count + 3, 0)
            End If
        Next
    Next

    ppts.ActivePresentation.Close
    FileName = Dir
Loop
End Sub


Sub ExtractTableContent(oTable As Object, rng As Range)
    Dim r, c, offR As Long, offC As Long

    For Each r In oTable.Rows '<< Loop over each row in the PPT table

        offC = 0 '<< reset the column offset

        For Each c In r.Cells '<< Loop over each cell in the row

            'Copy the cell's text content to Excel, using the offsets
            '    offR and offC to select where it gets placed relative
            '    to the starting point (rng)
            rng.Offset(offR, offC).Value = c.Shape.TextFrame.TextRange.Text

            offC = offC + 1 '<< increment the column offset

        Next c

        offR = offR + 1 '<< increment the row offset

    Next r

End Sub

Sub N()
Range("A3").Value = "New"
End Sub

【问题讨论】:

  • 在迁移数据时,我永远不会使用 PDF 作为中间格式:它不是为此而设计的。更可靠的方法是识别每个 Powerpoint 文件中的表格并直接提取数据。例如。这篇文章有一个可以用来开始的方法:stackoverflow.com/questions/4675100/…
  • 嗨,蒂姆,谢谢你的评论。我最初是从那个帖子开始的,忘记在上面提到我需要提取的 PPT 幻灯片是表格,而不是文本格式。鉴于:“sh.HasTextFrame”没有解决我幻灯片的 table 属性,你知道可以解决这个问题的函数吗?而且因为这是一个表格而不是文本,我不能只做一个简单的复制/粘贴宏:P
  • pptfaq.com/FAQ00790_Working_with_PowerPoint_tables.htm 展示了如何处理 PPT 表格中单个单元格的内容。获得对表对象的引用后,您可以循环遍历行和列以提取数据(例如到 Excel,或直接到 Access)
  • 谢谢!我会尝试一下并更新我的进度。
  • 在最后一次编辑中,您正在创建多个 PPT 实例(在循环中使用 New PowerPoint.Application)。您不需要这样做:只需在进入循环之前创建一个实例,并在完成后关闭它。

标签: vba excel csv ms-access powerpoint


【解决方案1】:

这是一个从 PPT 中提取表格到 Excel 的示例。

遍历幻灯片和表格(根据您发布的代码修改)

Sub Tester()

    Dim ppt As Object, tbl As Object
    Dim slide As Object, pres As Object, shp
    Dim rngDest As Range


    Set ppt = GetObject(, "Powerpoint.Application")

    Set pres = ppt.ActivePresentation

    Set rngDest = Sheets("Data").Range("a1") '<< where to start placing ppt data

    For Each slide In pres.Slides
        For Each shp In slide.Shapes
            If shp.HasTable Then
                ExtractTableContent shp.Table, rngDest
                Set rngDest = rngDest.Offset(shp.Table.Rows.Count + 3, 0)
            End If
        Next
    Next

End Sub

提取每个表数据的子:

Sub ExtractTableContent(oTable As Object, rng As Range)
    Dim r, c, offR As Long, offC As Long

    For Each r In oTable.Rows '<< Loop over each row in the PPT table

        offC = 0 '<< reset the column offset

        For Each c In r.Cells '<< Loop over each cell in the row

            'Copy the cell's text content to Excel, using the offsets
            '    offR and offC to select where it gets placed relative
            '    to the starting point (rng)
            rng.Offset(offR, offC).Value = c.Shape.TextFrame.TextRange.Text

            offC = offC + 1 '<< increment the column offset

        Next c

        offR = offR + 1 '<< increment the row offset

    Next r
End Sub

【讨论】:

  • 蒂姆,谢谢你的例子。我正在编写一个相当长的仅复制和粘贴值的解决方案。我对第二个 Sub 的循环有疑问。在 for r 的 For 循环中,发生了什么?我明白其他一切。我了解 For 循环中的嵌套操作正在识别列空间,但不确定如何阅读正在发生的事情。
  • 见上文 - 我已经对代码进行了注释,希望现在更清晰一些
  • 我一直在使用您的代码和其他一些花絮以及我的知识编写一个相当复杂的宏。我很欣赏你的洞察力,因为经过一些审查,我需要能够直接从 Powerpoint 中提取并为此编写一个循环。我已尝试按原样运行您的宏,并发现“ExtractTable”子没有作为宏填充。不知道为什么会这样。我在原始帖子中添加了一个编辑以供参考。
  • 我发布的代码是为 Excel VBA 编写的。你在为 Access VBA 写东西吗?
  • 没关系,我看到你在 PPT 中编码。您可能会发现从 Excel 运行整个程序要容易得多:这将使您免于在多个应用程序中进行编码。我稍后会更新我的帖子以添加更多内容。
【解决方案2】:

万一有人略过这个并想要使用该解决方案

它是开箱即用的,除了设置你的文件路径。

Sub Tester()
Dim rng As Range

Set rng = Range("A1")    'This code is necessary to prevent a constant loop of the formatting for each extraction. It adds a "1" into "A1"
rng.Value = 1


Dim ppts As PowerPoint.Application

Dim FolderPath As String
Dim FileName As String

FolderPath = "FolderPath"                'Define your Folder Path
FileName = Dir(FolderPath & "*.ppt*")    'Locate .PPT files

Do While FileName <> ""
    Set ppts = New PowerPoint.Application 'Left this in after finding another fix. Opens new instance each time
    ppts.Visible = True
    ppts.Presentations.Open FileName:=FolderPath & FileName
    'The code below sets 3 variables to help in formatting Tim's extraction code. 
    'It searches for the last cell entry and then adds 5 rows before copying more information.
    A = Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row + 5 
    B = "B" & A
    X = "A" & A
    Range(X).Value = "New" 

'Beginning of Tim's code
Dim ppt As Object, tbl As Object
Dim slide As Object, pres As Object, shp
Dim rngDest As Range


    Set ppt = GetObject(, "Powerpoint.Application")

    Set pres = ppt.ActivePresentation

    Set rngDest = Sheets("Data").Range(B) 'Moved it over one column for formatting

    For Each slide In pres.Slides
        For Each shp In slide.Shapes
            If shp.HasTable Then
                ExtractTableContent shp.Table, rngDest
                Set rngDest = rngDest.Offset(shp.Table.Rows.Count + 3, 0)
            End If
        Next
    Next

    ppts.ActivePresentation.Close    'Close PPT and loop for next one
    FileName = Dir
Loop
End Sub

'More of Tim's code

Sub ExtractTableContent(oTable As Object, rng As Range)
    Dim r, c, offR As Long, offC As Long

    For Each r In oTable.Rows '<< Loop over each row in the PPT table

        offC = 0 '<< reset the column offset

        For Each c In r.Cells '<< Loop over each cell in the row

            'Copy the cell's text content to Excel, using the offsets
            '    offR and offC to select where it gets placed relative
            '    to the starting point (rng)
            rng.Offset(offR, offC).Value = c.Shape.TextFrame.TextRange.Text

            offC = offC + 1 '<< increment the column offset

        Next c

        offR = offR + 1 '<< increment the row offset

    Next r

End Sub

Sub N()
Range("A3").Value = "New" 'Simply adds "New" next to each new file opened. Helps for deliniation between files
End Sub

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-23
    • 2016-05-22
    • 2014-12-30
    相关资源
    最近更新 更多