Select to view content in your preferred language

Custom table filled with data from an attribute table

735
6
05-13-2010 09:03 AM
JustinRiggs
Emerging Contributor
Hi all,

A bit of background:

My employer produces map books. In the map book, there is a table that was created in Excel, then pasted into the map book. The boss wants me to create a program that populates the cells of the table from an attribute table when an element is selected from a feature class. This will save our users loads of time, as they currently have to hand-enter all the data.

I've done some research, but don't see anything about creating dynamic tables. Is anybody aware of a script out there that does this?

To be specific, I'm looking for two things at the moment:

1) Any resource that would help me learn how to programatically create a table where a cell could receive data from an attribute table.
2) Code examples of how to access data in an attribute table and place it in a table cell (or text box, I guess).

Thanks for the help,

Justin
0 Kudos
6 Replies
JamesCrandall
MVP Alum
You might want to post what development environment and programing language you are working in.  Also, this is not a complete solution, but one implementation you could do would be to populate an ADO.NET DataTable object by looping thru the attribute table (sorry not inlcuded in this post as I don't have that portion handy at the moment and will have to add that at some point later on) then pass the dataTable to the function below...

Imports Excel = Microsoft.Office.Interop.Excel

Private Sub PopulateExcelTable(ByVal ADO_netDataTable As DataTable)

        Try
            Dim xlApp As Excel.Application
            Dim xlWorkBook As Excel.Workbook
            Dim xlWorkSheet As Excel.Worksheet

            xlApp = New Excel.ApplicationClass
            xlWorkBook = xlApp.Workbooks.Open("c:\test.xls") 'specify your .xls
            xlWorkSheet = xlWorkBook.Worksheets("sheet1")

            For i = 0 To ADO_netDataTable.Rows.Count - 2
                For j = 0 To ADO_netDataTable.Columns.Count - 1
                    xlWorkSheet.Cells(i + 1, j + 1) = ADO_netDataTable.Rows(i)(j).ToString
                Next
            Next

            xlWorkSheet.SaveAs("C:\test.xls") 'specify your .xls
            xlWorkBook.Close()
            xlApp.Quit()

        Catch ex As Exception
            MsgBox(ex.ToString)
        End Try

    End Sub
0 Kudos
JamesCrandall
MVP Alum
Ok, I whipped up the other portion real quick, so beware that while it seemed to work ok for me, it may not take into account all of the little things.  Basically, this is just to get you going and you really should extensively test for your implementation.

It's fairly simple, i just did all of this in one Class.  Just start it off with the click event of a button.  Here's the rest of the code you'll need

Good luck!!!

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

Dim pLayer As IFeatureLayer
pLayer = GetLayer("Add your layer name here")
   If pLayer Is Nothing Then
      MsgBox("Layer Not Found... Exiting")
      Exit Sub
   End If

buildTempDataTable(pLayer)

End Sub



You'll need to figure out how to get the m_pApp ref!

Private Function GetLayer(ByVal lyrName As String) As IFeatureLayer

        Dim pDoc As ESRI.ArcGIS.ArcMapUI.IMxDocument
        Dim pMap As ESRI.ArcGIS.Carto.IMap
        Dim pLayer As ESRI.ArcGIS.Carto.IFeatureLayer
        Dim i As Short
        'Layer name to find
        Dim sLayerName As String
        sLayerName = lyrName

        pDoc = m_pApp.Document
        pMap = pDoc.FocusMap

        For i = 0 To pMap.LayerCount - 1
            If pMap.Layer(i).Name = sLayerName Then
                pLayer = pMap.Layer(i)
                Exit For
            End If
        Next

        Return pLayer
    End Function



'this builds your ADO.NET DataTable. But may not add all required field types!!!

Private Sub buildTempDataTable(ByVal pLayer As IFeatureLayer)
        Dim tmpDT As New DataTable("tmpDT")
        Dim column As DataColumn

        Dim pTable As ITable = pLayer.FeatureClass
        Dim pFields As IFields = pTable.Fields
        Dim pCur As ICursor = pTable.Search(Nothing, False)

        For c = 0 To pCur.Fields.FieldCount - 1
            column = New DataColumn()
            column.ColumnName = (pFields.Field(c).Name)
            If pFields.Field(c).Type = esriFieldType.esriFieldTypeString Then
                column.DataType = System.Type.GetType("System.String")
            ElseIf pFields.Field(c).Type = esriFieldType.esriFieldTypeInteger Then
                column.DataType = System.Type.GetType("System.Int32")
            ElseIf pFields.Field(c).Type = esriFieldType.esriFieldTypeDouble Then
                column.DataType = System.Type.GetType("System.Double")
            ElseIf pFields.Field(c).Type = esriFieldType.esriFieldTypeDate Then
                column.DataType = System.Type.GetType("System.DateTime")
            End If


            column.ReadOnly = False
            tmpDT.Columns.Add(column)
        Next

        Dim pRow As IRow = pCur.NextRow
        Dim newRow As DataRow

        Do Until pRow Is Nothing

            newRow = tmpDT.NewRow()
            newRow.BeginEdit()
            For cols = 0 To pCur.Fields.FieldCount - 1
                newRow(cols) = pRow.Value(pRow.Fields.FindField(pFields.Field(cols).Name))
            Next
            newRow.EndEdit()
            tmpDT.Rows.Add(newRow)
            tmpDT.AcceptChanges()

            pRow = pCur.NextRow

        Loop


        PopulateExcelTable(tmpDT)

    End Sub



'This populates the Excel table

Private Sub PopulateExcelTable(ByVal ADO_netDataTable As DataTable)

        Try
            Dim xlApp As Excel.Application
            Dim xlWorkBook As Excel.Workbook
            Dim xlWorkSheet As Excel.Worksheet

            xlApp = New Excel.ApplicationClass
            xlWorkBook = xlApp.Workbooks.Open("c:\test.xls") 'specify your .xls
            xlWorkSheet = xlWorkBook.Worksheets("sheet1")

            For i = 0 To ADO_netDataTable.Rows.Count - 2
                For j = 0 To ADO_netDataTable.Columns.Count - 1
                    xlWorkSheet.Cells(i + 1, j + 1) = ADO_netDataTable.Rows(i)(j).ToString
                Next
            Next

            xlWorkSheet.SaveAs("C:\test.xls") 'specify your .xls
            xlWorkBook.Close()
            xlApp.Quit()

        Catch ex As Exception
            MsgBox(ex.ToString)
        End Try

    End Sub
0 Kudos
KirkKuykendall
Deactivated User
0 Kudos
JamesCrandall
MVP Alum
OP/Justin,

You'll need to specify what your dev environment is to get a more detailed solution.  Are you working with VBA, Visual Studio/.NET/C#, etc..?  I think Kirk's link to an older post/thread is specific to VBA (please correct me if I'm wrong on that Kirk).

Just to clarify... The example I provide above was from a VB.NET project I developed in VisualStudio2008 that when built creates a .dll and is added to ArcMap as a ToolBar (ultimately installed on a client workstation).

Please post if you have any success!
0 Kudos
JustinRiggs
Emerging Contributor
James, Kirk,

Thanks for your detailed replies. Both of them helped a great deal - in fact, I think James completed my *next* project for me! Just think how pleased my boss will be.

I'm afraid I wasn't as detailed or descriptive as I needed to be in this post. I'm going to start a new one today, and if either of you would like, I'd love to hear from you.

Thanks again for your help.

Justin
0 Kudos
JamesCrandall
MVP Alum
James, Kirk,

Thanks for your detailed replies. Both of them helped a great deal - in fact, I think James completed my *next* project for me! Just think how pleased my boss will be.

I'm afraid I wasn't as detailed or descriptive as I needed to be in this post. I'm going to start a new one today, and if either of you would like, I'd love to hear from you.

Thanks again for your help.

Justin


No problem -- you can start a new thread or post up a modification on this one.  Someone will help you come up with a solution I'm sure.  Please let me know if the ADO.NET DataTable approach works -- I've used this in several apps with a great deal of success and have realized other benefits like portability into other N-Tier architectures.  So, it's a good one to keep in mind IMO. 😉
0 Kudos