English 中文(简体)
我如何才能确保根据用户输入正确设定散射图的数据区域?
原标题:How can I ensure that the data ranges for the scatter plots are correctly set based on the user input?
  • 时间:2024-07-24 21:13:17
  •  标签:
  • excel
  • vba
I am working on a VBA project in Excel where I need to create scatter plots dynamically based on user input. The data is stored in a table, and the ranges for the scatter plots need to be determined dynamically. I have a script that generates a table based on user input. The table includes multiple series of data. I need to create three different scatter plots from this table, with the ranges for each plot determined by the user input. There are two different routines: one for building the table and another for creating the graphs. Here s the table: I ve tried export the endRow value from the for loop with the numSeries to a dictionary and exporting it. However, the exporting it somehow always get the wrong ranges no matter how I try. I am expecting it to be printing out 3 different graphs with X amount of series (based on user input). Here are the relevant VBA procedures I have so far: Routine 1: Build the Table Dim seriesEndRows() As Long Sub MainProcedure() Call AskForInput Call StoreEndRows Call MakeAllGraphs End Sub Sub AskForInput() User input and table generation code... End Sub Sub StoreEndRows() Dim wsControl As Worksheet Dim i As Integer, K As Integer Dim startRow As Long, seriesEndRow As Long Dim numSeries As Integer Dim seriesIndex As Integer Set wsControl = ThisWorkbook.Sheets("Control") startRow = 2 seriesIndex = 1 Initialize the series index ReDim seriesEndRows(1 To numVariables * numSeries) Adjust size as needed For i = 1 To numVariables Dim chkBox As MSForms.CheckBox Dim txtBox As MSForms.TextBox On Error Resume Next Set chkBox = UserForm1.Controls("CheckBox" & i) If chkBox Is Nothing Then Exit Sub On Error GoTo 0 If chkBox.Value = True Then On Error Resume Next Set txtBox = UserForm1.Controls("TextBox" & i) If txtBox Is Nothing Then Exit Sub On Error GoTo 0 numSeries = Val(txtBox.Text) Else numSeries = 1 End If For K = 1 To numSeries seriesEndRow = startRow Do Until wsControl.Cells(seriesEndRow, 1).Value = "" Find end of series seriesEndRow = seriesEndRow + 1 Loop seriesEndRow = seriesEndRow - 1 seriesEndRows(seriesIndex) = seriesEndRow Store the end row seriesIndex = seriesIndex + 1 startRow = seriesEndRow + 1 Next K Next i End Sub Routine 2: Creating the Graphs Sub MakeAllGraphs() Dim wsControl As Worksheet Dim chartObj As ChartObject Dim i As Integer Dim seriesEndRow As Long Dim seriesIndex As Integer Set wsControl = ThisWorkbook.Sheets("Control") Loop to create 3 graphs seriesIndex = 1 For i = 1 To 3 If seriesIndex <= UBound(seriesEndRows) Then seriesEndRow = seriesEndRows(seriesIndex) Else MsgBox "Series index " & seriesIndex & " exceeds array bounds." Exit Sub End If Set chartObj = wsControl.ChartObjects.Add(left:=100, width:=375, top:=50 + (i - 1) * 300, height:=225) With chartObj.Chart .ChartType = xlXYScatterLines Select Case i Case 1 Buckle vs RDI .SetSourceData Source:=wsControl.Range("K2:K" & seriesEndRow) .SeriesCollection.NewSeries .SeriesCollection(1).XValues = wsControl.Range("D2:D" & seriesEndRow) .SeriesCollection(1).Values = wsControl.Range("K2:K" & seriesEndRow) .SeriesCollection(1).Name = "Buckle vs RDI" Case 2 RDI vs Growth .SetSourceData Source:=wsControl.Range("J2:J" & seriesEndRow) .SeriesCollection.NewSeries .SeriesCollection(1).XValues = wsControl.Range("D2:D" & seriesEndRow) .SeriesCollection(1).Values = wsControl.Range("J2:J" & seriesEndRow) .SeriesCollection(1).Name = "RDI vs Growth" Case 3 RDI vs Flange Avg .SetSourceData Source:=wsControl.Range("H2:H" & seriesEndRow) .SeriesCollection.NewSeries .SeriesCollection(1).XValues = wsControl.Range("D2:D" & seriesEndRow) .SeriesCollection(1).Values = wsControl.Range("H2:H" & seriesEndRow) .SeriesCollection(1).Name = "RDI vs Flange Avg" End Select .HasTitle = True Select Case i Case 1 .ChartTitle.Text = "Buckle vs RDI" Case 2 .ChartTitle.Text = "RDI vs Growth" Case 3 .ChartTitle.Text = "RDI vs Flange Avg" End Select End With seriesIndex = seriesIndex + 1 Next i End Sub
问题回答
I might approach it something like this: Sub MakeAllGraphs() Dim wsControl As Worksheet Dim chartObj As ChartObject Dim i As Integer, ttl As String, xcol, ycol Dim seriesEndRow As Long Dim seriesIndex As Integer, col As Collection, rng As Range Set wsControl = ThisWorkbook.Sheets("Control") Set col = GetDataRanges() get data blocks wsControl.DrawingObjects.Delete delete existing plots For i = 1 To 3 assign title, x values column, y values column Select Case i Case 1 ttl = "Buckle vs RDI" xcol = "D" ycol = "K" Case 2 ttl = "RDI vs Growth" xcol = "D" ycol = "J" Case 3 ttl = "RDI vs Flange Avg" xcol = "D" ycol = "H" End Select Set chartObj = wsControl.ChartObjects.Add(Left:=100, Width:=375, _ Top:=50 + (i - 1) * 300, Height:=225) With chartObj.Chart .ChartType = xlXYScatterLines .HasTitle = True .ChartTitle.Text = ttl For Each rng In col With .SeriesCollection.NewSeries .XValues = rng.Columns(xcol) .Values = rng.Columns(ycol) .Name = rng.Cells(1).Value & ":" & rng.Cells(2).Value End With Next rng End With Next i End Sub return a collection of ranges, where each range is a block of rows representing a series variable Function GetDataRanges() As Collection Const START_ROW As Long = 2 Dim col As New Collection, ws As Worksheet, lr As Long Dim c As Range, m Set ws = ThisWorkbook.Worksheets("Control") lr = ws.Cells(Rows.Count, "A").End(xlUp).Row last used row Set c = ws.Cells(START_ROW, "A") starting here Do find the next "Max" in Col A m = Application.Match("Max", c.Offset(1).Resize(100), 0) If Not IsError(m) Then col.Add c.EntireRow.Resize(m) add the rows for this block to the collection Set c = c.Offset(m + 4) skip to next start row Else Exit Do no more data End If Loop Set GetDataRanges = col End Function




相关问题
import of excel in SQL imports NULL lines

I have a stored procedure that imports differently formatted workbooks into a database table, does work on them then drops the table. Here is the populating query. SELECT IDENTITY(INT,1,1) AS ID ...

Connecting to Oracle 10g with ODBC from Excel VBA

The following code works. the connection opens fine but recordset.recordCount always returns -1 when there is data in the table. ANd If I try to call any methods/properties on recordset it crashes ...

Excel date to Unix timestamp

Does anyone know how to convert an Excel date to a correct Unix timestamp?

C# GemBox Excel Import Error

I am trying to import an excel file into a data table using GemBox and I keep getting this error: Invalid data value when extracting to DataTable at SourceRowIndex: 1, and SourceColumnIndex: 1. As ...

Importing from excel "applications" using SSIS

I am looking for any tips or resources on importing from excel into a SQL database, but specifically when the information is NOT in column and row format. I am currently doing some pre-development ...

热门标签