VBA Macro to extract data from a chart in Excel 2007, 2010, and 2013 -


i sent excel sheet 4 charts. data charts in workbook not provided.

goal: want extract data charts using vba sub.

problem: having trouble "type mismatch." when try assign variant array oseries.xvalues range of cells.

option explicit option base 1 ' 1. enter following macro code in module sheet. ' 2. select chart want extract underlying data values. ' 3. run getchartvalues sub. data chart placed in new worksheet named "chartname data". ' sub getchartvalues()     '     dim lxnumberofrows long     dim lynumberofrows long     dim oseries series     dim lcounter long     dim oworksheet worksheet     dim ochart chart     dim xvalues() variant     dim yvalues() variant     dim xdestination range     dim ydestination range       set ochart = activechart     ' if chart not active, exit     if ochart nothing         exit sub     end if      ' create worksheet storing data     set oworksheet = activeworkbook.worksheets.add     oworksheet.name = ochart.name & " data"       ' loop through series in chart , write there values     ' worksheet.     lcounter = 1     each oseries in ochart.seriescollection          xvalues = oseries.xvalues         yvalues = oseries.values          ' calculate number of rows of data. 1048576 maximum number of rows in excel.         lxnumberofrows = worksheetfunction.min(ubound(oseries.xvalues), 1048576 - 1)         lynumberofrows = worksheetfunction.min(ubound(oseries.values), 1048576 - 1)          ' array big, chop off end         redim preserve xvalues(lxnumberofrows)         redim preserve yvalues(lynumberofrows)           oworksheet             ' put name of series @ top of each column             .cells(1, 2 * lcounter - 1) = oseries.name             .cells(1, 2 * lcounter) = oseries.name              set xdestination = .range(.cells(1, 2 * lcounter - 1), .cells(lxnumberofrows + 1, 2 * lcounter - 1))             set ydestination = .range(.cells(1, 2 * lcounter), .cells(lxnumberofrows + 1, 2 * lcounter))              'assign x , y data chart range in worksheet              xdestination.value = application.transpose(xvalues)              ydestination.value = application.transpose(yvalues)              ' not work either             ' .range(.cells(2, 2 * lcounter - 1), .cells(lxnumberofrows + 1, 2 * lcounter - 1)).value = application.transpose(oseries.xvalues)             ' .range(.cells(2, 2 * lcounter), .cells(lxnumberofrows + 1, 2 * lcounter)).value = application.transpose(oseries.values)           end          lcounter = lcounter + 1     next      ' cleanup     set ochart = nothing     set oworksheet = nothing  end sub 

the main issue following lines:

.range(.cells(2, 2 * lcounter - 1), .cells(lxnumberofrows + 1, 2 * lcounter - 1)) = application.transpose(oseries.xvalues) .range(.cells(2, 2 * lcounter), .cells(lxnumberofrows + 1, 2 * lcounter)) = application.transpose(oseries.values) 

upon further inspection using locals window, find following: enter image description here

the below code works while above code not.

sub test2() dim a(6) variant 'a(1) = 1 a(2) = 2# a(3) = 3# a(4) = 4# a(5) = 5# range(cells(1, 1), cells(6, 1)).value = application.transpose(a) end sub 

why doesn't first piece of code work?

looping on many cells slow in case (i've tried). please, don't use loop unless seconds 1,000,000 element.

the main cause built-in transpose function. transpose can handle arrays 2^16 or less elements.

the code below works well. handles problem of transpose function limitation of 2^16 elements. uses loop loop fast arrays. 4 series , each having 1048576 elements, sub took 10 seconds run. acceptable.

option explicit option base 1 ' 1. enter following macro code in module sheet. ' 2. select chart want extract underlying data values. ' 3. run getchartvalues sub. data chart placed in new worksheet named "chartname data". ' public sub getchartvalues()      dim lxnumberofrows long     dim lynumberofrows long     dim oseries series     dim lseriescounter long     dim oworksheet worksheet     dim ochart chart     dim xvalues() variant     dim yvalues() variant     dim xdestination range     dim ydestination range       set ochart = activechart     ' if chart not active, exit     if ochart nothing         exit sub     end if      ' create worksheet storing data     set oworksheet = activeworkbook.worksheets.add     oworksheet.name = ochart.name & " data"       ' loop through series in chart , write values worksheet.     lseriescounter = 1     each oseries in ochart.seriescollection         ' x , y values         xvalues = oseries.xvalues         yvalues = oseries.values          ' calculate number of rows of data.         lxnumberofrows = ubound(xvalues)         lynumberofrows = ubound(yvalues)          ' 1048576 maximum number of rows in excel. array big. chop off end.         if lxnumberofrows >= 1048576             lxnumberofrows = 1048576 - 1             redim preserve xvalues(lxnumberofrows)         end if         if lynumberofrows >= 1048576             lynumberofrows = 1048576 - 1             redim preserve yvalues(lynumberofrows)         end if          oworksheet             ' put name of series @ top of each column             .cells(1, 2 * lseriescounter - 1) = oseries.name & " x values"             .cells(1, 2 * lseriescounter) = oseries.name & " y values"             set xdestination = .range(.cells(2, 2 * lseriescounter - 1), .cells(lxnumberofrows + 1, 2 * lseriescounter - 1))             set ydestination = .range(.cells(2, 2 * lseriescounter), .cells(lxnumberofrows + 1, 2 * lseriescounter))         end           ' arrays larger 2^16 fail transpose function. therefore must manually transpose         if lxnumberofrows > 2& ^ 16              'assign x , y data chart range in worksheet. use manualtranspose  2^16 or more elements.              xdestination.value = manualtranspose(xvalues)              ydestination.value = manualtranspose(yvalues)         else              'assign x , y data chart range in worksheet. use built-in transpose less 2^16 elements.             xdestination.value = worksheetfunction.transpose(xvalues)             ydestination.value = worksheetfunction.transpose(yvalues)         end if          lseriescounter = lseriescounter + 1     next      ' cleanup     set ochart = nothing     set oworksheet = nothing  end sub  ' helper function when built-in transpose function cannot used. arrays larger 2^16 must transposed manually. private function manualtranspose(byref arr variant) variant     dim arrlength long     dim long     dim transposedarray() variant      arrlength = ubound(arr)      redim transposedarray(arrlength, 1)      = 1 arrlength         transposedarray(i, 1) = arr(i)     next      manualtranspose = transposedarray end function 

Comments

Popular posts from this blog

javascript - Using jquery append to add option values into a select element not working -

Android soft keyboard reverts to default keyboard on orientation change -

Rendering JButton to get the JCheckBox behavior in a JTable by using images does not update my table -