How to resize a shape using CellsSRC? - vba

I'd like to resize a shape (a line to be specific), I know it's possible to move a line with cellsSRC using the following line :
element.CellsSRC(visSectionObject, visRowXFormOut, visXFormBeginX).result("in") = 0.1
but is it possible to change the size of a line using cellsSRC ? and how to do so ? Thank you very much in advance

I don't know what you mean by 'change the size of a line', as a line has begin and end points in Visio, and are considered one dimensional. There's a thickness, which is controlled separately.
You can use CellsU to control the begin and end points, which is just easier than knowing the SRC address. So there are four cells: BeginX, BeginY, EndX, EndY, which specify the x and y coordinates of the begin and end points.
So to move the begin point to 1,2:
element.cellsU("BeginX").formula = "1"
element.cellsu("BeginY").formula = "2"

Related

Can't use all arguments with Shapes to control line in the GraphicsWindow

After trying a few things inside small basic to make a line follow the mouse but not move the entire line, I recently came across a problem. Originally I was trying to constantly have a line update so as it stays connected from one point to the mouse position by clearing the graphics window and redrawing a line from the bottom right to the mouse. This could not work and was to resource intensive. However, now I have come across Shape.addline and shape.move. But I'm not too sure as to how they work, from my understanding, a shape can have it's own name by doing:
[Shapename] = Shapes.addline(positions)
and then that shape can be moved using:
Shapes.move(Shapename,Coordinates)
In my case it's:
L1 = Shapes.AddLine(0,GraphicsWindow.Height,GraphicsWindow.MouseX,GraphicsWindow.MouseY)
(Drawing a line from the bottom left corner to the mouses position)
and
Shapes.Move(L1,GraphicsWindow.MouseX,GraphicsWindow.MouseY)
The only problem is that Shapes.Move only supports 3 arguments being:
shapeName
X
Y
But, when drawing the line (Shapes.AddLine), I use 4 arguments:
X1
Y1
X2
Y2
This means I can only control those two positions. So, how would you control the other two? If we can only modify X1 and Y1, is there any way of still using at least something similar to the shape.move method but be able to control the other X2 and Y2 positions? Primarily, I would like to actually Only change the X2 and Y2 positions, as I'm trying to make a line originate from one point and stay there, then alter the opposing point so that it follows the mouse, and not move the entire shape. If none of this is possible, is there any known way of moving / changing only the X2 and Y2 coordinates of a line without having to clear the entire screen?
Ah yes. These are the shortcomings of small basic. Shapes.move will not let you define a starting and ending point of a line. What you will need to do is move the center of the line in between the first point and the cursor, and the rotate it correctly. Like so:
Mouseline = Shapes.AddLine(0,0,100,0)
Shapes.Move(Mouseline,200,200)
GraphicsWindow.MouseMove = OnMouseMove
Sub OnMouseMove
XDif = (GraphicsWindow.MouseX-250)
YDif = (GraphicsWindow.MouseY-200)
If XDif <> 0 Then
MouseAngle = Math.ArcTan(YDif/XDif)
EndIf
If XDif < 0 Then
MouseAngle = MouseAngle + 3.14 '180 degrees in radians
EndIf
Shapes.Rotate(Mouseline,Math.GetDegrees(MouseAngle))
Shapes.Move(Mouseline,(Math.Cos(MouseAngle)*50)+200,(Math.Sin(MouseAngle)*50)+200)
EndSub
Another way of doing this is with the LitDev extension (http://litdev.co.uk/). It has a MoveLine(x1,y1,x2,y2) function in it.
im guessing u would alter the end of the program where it says math.cos(mouseangle) change the 200 to 0 and change the other 200 to the bottom. so if what im trying to figure out, ur trying to get the line to only project in the 1st quadrant in a cortesian plane yes?

Finding the absolute position of a character in MS Word

Is it possible to find the position of a character in Microsoft Word?
By that I mean, let's say I want to create a macro to join up two full stops with a line. I can draw a line using x and y for the start and end points.
If I type a full stop character, is it possible to get the exact positioning of that character on the page? If so, it would then be possible to join two of these, but I would like to know if it is possible to get the X and Y positions for any character on the page.
This code will show the relative position of the current selection point. Just remember that a "page" in word is a moving target determined by the amount of text, margins, paper size, etc.
Sub getPosition()
Debug.Print Selection.Information(wdVerticalPositionRelativeToPage)
Debug.Print Selection.Information(wdHorizontalPositionRelativeToPage)
End Sub
ยจ

How to cut out numbers from an image dynamically?

i've got to this stage:
where i can find the numbers in the above image but i need to cut them out so i can retain the order etc. but the as the number increases the spacing changes and the position of the number?
so i think it should be a find a white PX the continue until it find a solid black col and then use the points to do a simple cut any help would be great.
A simple solution would be this:
Find the first upmost horizontal line which contains white pixels
From that line find the first horizontal line which contains only black pixels
Those two lines are your upper and lower borders.
Between this borders proceed like this:
Find the first most left vertical line which contains white pixels
From that line find the last vertical line which contains only black pixels and which comes directly after a line with white pixels.
Those two lines are your left and right borders.
The steps to separate single numbers can be performed analogously.
If you need to identify which numbers are in your picture, I recommend using specialized computer vision libraries.
Some VB.net pseudo code to get you going:
Sub FindTopBorder(image As MyImage) As Integer
For y = 0 to image.Height - 1
For x = 0 to image.Width - 1
Dim pixel = image.GetPixel(x, y)
If ('Check if pixel is white here with RGB or Color') Then
Return y
End If
Next
Next
' Just in case there are no white pixels or use an exception instead
Return -1
End Sub
I would start looking into Connected component segmentation. You find a pixel which is within a character (number). Then run the connected component algorithm which finds all connected pixels under specific set of rules (e.g. slight deviation in color, stop at hard borders etc).
http://en.wikipedia.org/wiki/Connected-component_labeling
If you can use libraries, I'm sure OpenCV or similar libraries support this out of the box.
//edit
I see you need VB.net. Probably it is easiest to port some algorithm to VB or create one yourself.
See e.g. http://www.codeproject.com/Articles/336915/Connected-Component-Labeling-Algorithm
What to expect
Input
An image containing two shapes:
Output
Now each is separated into single images.

Attaching a Textbox to a point or line on a chart in Excel/VBA

I was wondering how to attach a textbox to a point or line in an Excel chart for the macro I am working on. I have been using the .AddTextbox method such as
.Shapes.AddTextbox(msoTextOrientationHorizontal, 150, 250, 100, 15) _
.TextFrame.Characters.Text = "Temperature"
But I have to then manually drag the textbox over the line on the chart it is representing as the orientation is of the chart not the line. Is there a way to convert the line/point to a chart orientation which I could use as a variable? or another way? Possibly using the datalabel function, though I want to be able to customize one of the axis locations. Thanks
To solve your question you need to get the left & top position of two objects:
chart itself, which position is set in relation to top-left corner of sheet range area
point in series which position is set in relation to top-left corner of chart
Combination of both result with the following code (fixed parameters-required changes to your situation, could be more dynamic with loop)
Sub Add_Text_to_point()
Dim tmpCHR As ChartObject
Set tmpCHR = Sheet1.ChartObjects(1) 'put index of your chartobject here
'for first serie, for point 2nd here
'(change accordingly to what you need)
With tmpCHR.Chart.SeriesCollection(1).Points(2)
Sheet1.Shapes.AddTextbox(msoTextOrientationHorizontal, _
.Left + tmpCHR.Left, _
.Top + tmpCHR.Top, _
100, 15) _
.TextFrame.Characters.Text = "Temperature"
End With
End Sub
After result presenting the picture below.
Another option would be to use the data labels of Excel. I see two more elegant options:
Make a new data series with just one entry in your chart, give the series the coordinates and the name of the label you want to see. Now activate the marker option for the series (if not done already), right-click on the data point, click "add data labels". Now you'll see the y-Value of the point. By right-clicking again and choosing "Format Data Labels" you can change the text to the series name, also the position, the border, etc. are modifiable. Below an example with two data points. You could delete the second point, the line and the marker but like this you see how it works.
Similarly to the solution from KazJaw you can use the actual data points of your series for attaching custom data labels. This requires some coding, I used this for the chart named "Topview" and wrote percentages next to the data point
Sub Add_Text_to_data_points()
percentages(1) = 0.1
percentages(2) = 0.23
'.... further entries
chartNumber = findChartNumber("Topview")
collNumber = 12 ' index of the "points" series
Set tmpCHR = ActiveSheet.ChartObjects(chartNumber)
For i = 1 To tmpCHR.Chart.SeriesCollection(collNumber).Points.count
With tmpCHR.Chart.SeriesCollection(collNumber).Points(i)
If percentages(i) <> 0 Then
.DataLabel.Text = format(percentages(i), "0%")
End If
End With
Next
End Sub

Change the color for each line

I got a console application that draws line in a 3D CAD program. Now to make this more clear i want to change these lines in different colors.
My code read variables from a text-file and calculates data from it and then makes a lines from this calculated data.
This process gets repeated with every line in the text file wich contains data.
Now i want visual basic to change the color everytinme a new line is drawn, so i get different colored lines.
I tried using a For.. To.. Step method, but this didnt work. I also tried to use the variables from my text file( these are different so when a new line got read the RGB code will change) but this will geve me only a lot of blue colors.
Any suggestions?
EDit:
This is what i use to draw the curves, the RGB code has to cahnge everytime when a line with new data is made:
' Creating a Curve2d object by using the above defined points
objLineString = objLineStrings.AddByPoints(PointCount:=points, points:=dataArray)
objGeometricStyle = objLineString.Style
color = objGeometricStyle.LinearColor
objGeometricStyle.LinearColor = RGB(0,0,0)
What about :
Dim rand As New Random() ' Used to generate random numbers
Dim colors(100) as Integer
' Create the colors
For i as Integer = 0 to 100 Step 1
colors(i) = RGB(rand.Next(256), rand.Next(256), rand.Next(256))
Next
For i As Integer = 0 To 100 Step 1 ' Adjust to your needs
' Creating a Curve2d object by using the above defined points
objLineString = objLineStrings.AddByPoints(PointCount:=points, points:=dataArray)
objGeometricStyle = objLineString.Style
color = objGeometricStyle.LinearColor
objGeometricStyle.LinearColor = colors(i Mod 100) ' Mod returns the remainder of i / 100, so it's always less than 100.
Next
This won't always give you "pretty" colors, but they'll be different for each line. If you want control over the generated colors, you could set up an array of predefined colors and use these in your iteration.