VBA Dynamic XY Series plotting - excel

I have some code that is supposed to plot multiple series of data to a single chart all from 2 columns (X and Y values) of data. I have it currently set up such that the if statement checks the "ID" that is constant for a single series in another column of data, and will plot a new series once the "ID" changes to signify a new series, and will then plot to the chart.
The code will cycle through, and I can watch it plot each series I want on the chart, however after executing the chart will only have the last of the series in the two columns plotted. I can check the chart afterwards and see the series have been generated, but all of them are dataless aside from the last in the column. Below is my code and I appreciate any comments.
For i = datastart To dataend
If ws1.Cells(i, 3).Value <> ws1.Cells(i + 1, 3).Value Then
Z = i - k + j
t = i - k + 1
With Chart5
.PlotArea.Select
.SeriesCollection.NewSeries
.SeriesCollection(t).Name = ws1.Cells(i, 3).Value
.SeriesCollection(t).XValues = "=Data!$G$" & Z & ":$G$" & i
.SeriesCollection(t).Values = "=Data!$F$" & Z & ":$F$" & i
End With
j = i
Else
k = i
End If
Next i
I am currently at just getting this functioning.

How about this:
' ... some other code
.SeriesCollection.newSeries
t = .SeriesCollection.Count
.SeriesCollection(t).Name = ws1.Cells(i, 3).Value
.SeriesCollection(t).XValues = "=Data!$G$" & z & ":$G$" & i
.SeriesCollection(t).Values = "=Data!$F$" & z & ":$F$" & i
' ... some other code

Related

How Do I Loop through Worksheet and Detect Duplicate Lines based on Certain Column Values?

I am writing a macro that will loop through a worksheet to detect duplicate lines in a product log. I need it to look at the UPC (Column A), Expiration Date (Column E), and Location (Column H).
I have the first loop running from 2 to LastRow which is the value of srcSheet.Cells(Rows.Count, "A").End(xlUp).Row. I assign variables the values of Range A/E/H:x and then have a second loop running from LastRow to 3 with a -1 step.
The problem I am having is that when I add a second condition, using either And or a nested If/Then, every line will match. I have that MsgBox output a message and show me the values of x and y.
If I am only checking one pair of values, like chkUPC and srcUPC, I will see everything fine. When I add the second condition, chkExpDate = srcExpDate, it will find every line is a duplicate and when I output the values of x and y, they will match so rather than comparing Row 2 to Row 1950 for the first run, it will be comparing row 3 to iteself.
Here is the code:
srcLastRow = srcSheet.Cells(Rows.Count, "A").End(xlUp).Row
For x = 2 To srcLastRow
srcUPC = srcSheet.Range("A" & x).Value
srcExpDate = srcSheet.Range("E" & x).Value
srcQty = srcSheet.Range("G" & x).Value
srcLocation = srcSheet.Range("H" & x).Value
For y = srcLastRow To 3 Step -1
chkUPC = srcSheet.Range("A" & y).Value
chkExpDate = srcSheet.Range("E" & y).Value
chkQty = srcSheet.Range("G" & y).Value
chkLocation = srcSheet.Range("H" & y).Value
If chkUPC = srcUPC And chkExpDate = srcExpDate Then
MsgBox "The same product has been found on multiple lines" & vbCrLf & x & " | " & y
End If
Next y
Next x
Try changing
For y = srcLastRow To 3 Step -1
to
For y = srcLastRow To x+1 Step -1
otherwise it will compare every line except the second one with itself.

Find Distance between different coordinates

I have Location data (latitude and longitude) of 1000's of locations and need to compute the distance between each of them taken two combinations at a time.
Example:
Let's just say I have four location data (latitude and longitude data) and want to compute the distance between them
Location Latitude Longitude
1. New York(L1) 40.7128° N 74.0060° W
2. Paris(L2) 48.8566° N 2.3522° E
3. London(L3) 51.5074° N 0.1278° W
4. Moscow(L4) 55.7558° N 37.6173° E
Need to calculate the distance between possible combinations i.e distance between L1&L2, L1&L3, L1&L4, L2&L3, L2&L4 and L3&L4
Excel Formula I'm using to compute distance is
=ACOS(COS(RADIANS(90-Lat1)) *COS(RADIANS(90-Lat2)) +SIN(RADIANS(90-Lat1)) *SIN(RADIANS(90-Lat2)) *COS(RADIANS(Long1-Long2))) *6371
How can I calculate it for large data set say 100's or 1000's of locations?
Alternatively, you can create a VBA function and then loop through your table.
Add this code to a Module in the VBA editor:
Public Function DistBetweenCoord(Lat1 As Double, Long1 As Double, Lat2 As Double, Long2 As Double)
'Cell Formula
'ACOS(COS(RADIANS(90-Lat1)) *COS(RADIANS(90-Lat2)) +SIN(RADIANS(90-Lat1)) *SIN(RADIANS(90-Lat2)) *COS(RADIANS(Long1-Long2))) *6371
With WorksheetFunction
A = Cos(.Radians(90 - Lat1))
B = Cos(.Radians(90 - Lat2))
C = Sin(.Radians(90 - Lat1))
D = Sin(.Radians(90 - Lat2))
E = Cos(.Radians(Long1 - Long2))
DistBetweenCoord = .Acos(A * B + C * D * E) * 6371
End With
End Function
Now you can access this through code or in cell. Here is an example of in-cell:
=DistBetweenCoord(C1,D1,C2,D2)
Here is how to loop through all possible combinations in another Sub. Output is in immediate window.
Sub CalcAllDistances()
With Worksheets("Sheet1")
For i = 1 To 4
For j = i To 4
If i <> j Then
Debug.Print .Cells(i, 2) & " to " & .Cells(j, 2) & ": " & DistBetweenCoord(.Cells(i, 3), .Cells(i, 4), .Cells(j, 3), .Cells(j, 4))
End If
Next j
Next i
End With
End Sub
EDIT - To change output to Sheet2 try the following:
Sub CalcAllDistances()
Dim wks_Output As Worksheet
Set wks_Output = Worksheets("Sheet2")
Dim OutputRow As Long: OutputRow = 1
With Worksheets("Sheet1")
For i = 1 To 4
For j = i To 4
If i <> j Then
wks_Output.Cells(OutputRow, 1).Value = .Cells(i, 2) & " to " & .Cells(j, 2)
wks_Output.Cells(OutputRow, 2).Value = DistBetweenCoord(.Cells(i, 3), .Cells(i, 4), .Cells(j, 3), .Cells(j, 4))
OutputRow = OutputRow + 1
End If
Next j
Next i
End With
End Sub
I would use a matrix.
Create a sheet (like 'GeocodeList' or something) for the geocodes, like your city|lat|lon in the question. Then create a sheet (like 'Distances') for a matrix, where the column and row labels are the city names. Then you can parameter your excel formula using V.LOOKUPs that look up exact codes from GeocodeList.
The formula would look like this (X is row number, Y is column letter.):
=ACOS(COS(RADIANS(90-VLOOKUP($A(X); GEOCODETABLE, LATCOLINDEX, 0)))
*COS(RADIANS(90-VLOOKUP((Y)$1; GEOCODETABLE; LATCOLINDEX, 0)))
+SIN(RADIANS(90-VLOOKUP($A(X); GEOCODETABLE, LATCOLINDEX, 0)))
*SIN(RADIANS(90-VLOOKUP((Y)$1; GEOCODETABLE; LATCOLINDEX, 0)))
*COS(RADIANS(VLOOKUP($A(X); GEOCODETABLE, LATCOLINDEX, 0)-VLOOKUP((Y)$1; GEOCODETABLE; LONCOLINDEX, 0))))
*6371
So basically the VLOOKUP automatically fetches your parameters, and you can extend the formula for the whole matrix.

How to plot data imported from a csv?

I am trying to import CSV output data from a simulation into an Excel sheet to plot the data in a regular XY scatter chart.
I managed everything except the end result. The data is imported from csv to Excel, points are replaced by commas as a decimal separator.
It is plotting a straight horizontal line at 0 y-coordinates.
I noticed that the values in Excel are stored as texts, although I specified the format for numerical contents of csv as numbers like following:
DataSheet.Cells(Row, col).NumberFormat = "0.E+00"
When I test Isnumeric(cell.value), it turns out positive.
My complete code:
CsvFile = Application.GetOpenFilename()
Set DataSheet = Worksheets("CSV_Plot")
nrow = 10 'data starts at 10th row
Open CsvFile For Input As #1
Do Until EOF(1)
Line Input #1, CsvLine
CsvItem = Split(CsvLine, ",")
If Not CsvItem(0) <> "" Then GoTo 10 'ignores first line
ncol = UBound(CsvItem) 'ncol = number of data columns
If IsNumeric(CsvItem(0)) Then
For i = 0 To ncol
CsvItem(i) = Replace(CsvItem(i), ".", ",") 'replace point with comma in 'numerical values
Next i
End If
Add1 = DataSheet.Cells(nrow, LBound(CsvItem) + 1).Address
Add2 = DataSheet.Cells(nrow, ncol + 1).Address
DataSheet.Range(Add1 & ":" & Add2) = CsvItem
nrow = nrow + 1
10:
Loop
nrowlast = nrow
Close #1
For Row = 11 To nrowlast
For col = 1 To ncol
DataSheet.Cells(Row, col).Select
DataSheet.Cells(Row, col).NumberFormat = "0.E+00"
Next col
Next Row
Set ChtObj = DataSheet.ChartObjects.Add(50, 50, 500, 300)
Set Cht = ChtObj.Chart
With Cht
.ChartType = xlXYScatterLines
.SeriesCollection.NewSeries
.SeriesCollection(1).XValues = DataSheet.Range("A11:A35")
.SeriesCollection(1).Values = DataSheet.Range("N11:N35")
End With
EDIT: I think your problem is this line: CsvItem = Split(CsvLine, ","). The return type of Split should be a String. I don't know what your data looks like but you could try casting it as Double if decimal places are relevant. Otherwise cast it as Long: CsvItem = CLng(Split(CsvLine, ",")).
Original answer:
I updated the relevant parts of your code:
For Row = 11 To nrowlast
For col = 1 To ncol
DataSheet.Cells(Row, col).NumberFormat = "0.E+00"
Next col
Next Row
I took out the .Select statement as it is unnecessary and might lead to errors. Here is the main part part:
Dim ChtObj As Object
Set ChtObj = DataSheet.Shapes.AddChart2(, xlXYScatterLines, 50, 50, 500, 300)
With ChtObj.Chart
.SeriesCollection.NewSeries
.SeriesCollection(1).XValues = DataSheet.Range("A11:A35")
.SeriesCollection(1).Values = DataSheet.Range("N11:N35")
End With
This should work as intended.
After some effort, i was able to locate the source of problem: I had defined CsvItem() as string and that's why when I execute the statement DataSheet.Range(Add1 & ":" & Add2) = CsvItem, the values in excel were always text irrespective of the format.
The solution to this was to define a variable to hold numerical values of CsvItem and assign this value to excel cells:
Dim CsvVal() As Double
CsvVal(i) = CDbl(CsvItem(i))
DataSheet.Range(Add1 & ":" & Add2).Value = CsvVal
this eventually produced the result I wanted.

Unable to plot values on scatterplot using vba

I am relatively new to VBA. I am attempting to automate the generation of a graph containing Beta values using the following steps:
Step 1 - Generate a list of random numbers in Column A
Step 2 - Based on values in Column A, apply the Beta.Dist formula in Column B
Step 3 - Generate a scatterplot based on values in Column B, the scatterplot should look like a U-shaped distribution curve
I've tried using the following code but I am only seeing 1 value in the scatter plot (i.e., the scatterplot only has one dot).
Here's the code:
Option Explicit
Option Base 1
Sub Macro1()
Application.ScreenUpdating = False
Dim i%, j%
Range("A1").Select
Selection = "0.99"
Selection.Offset(0, 1) = "Beta(" & Selection & ", " & Selection & ") Density"
For i = 1 To 301
Selection.Offset(i, 0).Formula = "= rand()"
Selection.Offset(i, 1).Formula = "=BETA.DIST(A2:A302,0.99,0.99,False)"
Next i
j = ActiveSheet.ChartObjects.Count
ActiveSheet.Shapes.AddChart2(-1, xlXYScatter, 98 + j * 10, 16.5 + j * 10, 319, 296.5).Select
ActiveChart.SetSourceData Source:=Sheets("Sheet1").Range("B2:B302")
ActiveSheet.ChartObjects(j + 1).Activate
ActiveChart.SetElement (msoElementChartTitleAboveChart)
Selection.Caption = "="
ActiveChart.Axes(xlCategory).MaximumScale = 1
ActiveChart.Axes(xlCategory).Format.Line.Visible = msoFalse
ActiveChart.Axes(xlCategory).MajorGridlines.Delete
ActiveChart.Axes(xlValue).MaximumScale = 1.1
ActiveChart.Axes(xlValue).TickLabels.NumberFormat = "0.000#"
ActiveChart.Axes(xlValue).Format.Line.Visible = msoFalse
ActiveChart.Axes(xlValue).MajorGridlines.Delete
Range("E1") = ""
Range("I1") = ""
Range("B1").Select
Application.ScreenUpdating = True
End Sub
I'm hoping to get a U-shaped beta distribution curve in the scatter plot. Appreciate any form of help and thank you in advance!
You're not setting the chart data correctly:
ActiveChart.SetSourceData Source:=Sheets("Sheet1").Range("A2:B302")

Chart Naming with Variable in VBA, Excel 2013

I was trying to rename a chart with:
With ActiveChart
For i = 1 To Count_Rows
j = i + 1
.FullSeriesCollection(i).Name = """=Sheet1!$A$" & j & Chr(34)
Next i
...
this is resolving to desired formula as "=Sheet1!$A$2" and so on...
but not naming the series with contents instead putting the name of the series as "=Sheet1!$A$2"
You are not using a range object to return the cell values.
For i = 1 To Count_Rows
j = i + 1
.FullSeriesCollection(i).Name = Range("Sheet1!$A$" & j)
Next i

Resources