Can VBA detect line-wrapping in an Excel chart legend? - vba

Context
Writing to code to format a chart (all of which should be done by Microsoft, but that’s separate).
Am now positioning the legend. Taking a 9×9 block of possible positions, and counting the data points underneath each. As a fragment of the code: (ax.MaximumScale - ax.MinimumScale) * co.Chart.Legend.Width / co.Chart.PlotArea.InsideWidth.
Also coping with lines underlapping and text boxes overlapping the possible legend positions: same idea, more complexity.
Question
Obviously, all this works better if the legend is as small as possible, as that gives a greater likelihood of finding a location with zero ’lapping.
If .Legend.Width is too small, then the individual legend texts (the Series.Name’s) wrap onto ≥2 lines, which isn’t wanted. So VBA could interval bisect to find the smallest .Legend.Width for which there isn’t line wrapping. But how can the VBA code ‘see’|‘detect’|‘know’ of the existence of the line wrapping?
And mutatis mutandis for .Legend.Height: if that’s too small, some legend entries aren’t shown. How can the VBA code ‘see’|‘detect’|‘know’ that a height is too small?
Thank you.
PS: I expect that the correct answer is that “VBA cannot ‘see’|‘detect’|‘know’ either of these.” Please refute this expectation.

If you create your own legend, using a text box, you have better options when it comes to sizing and flow control. This will create a new set of challenges, but it might be easier to handle.

Related

How to make long text fit into a text_frame? Python-pptx

I'm working with python-ppt to create a portfolio of candidates in a Powerpoint presentation. There is one candidate per slide and each of them has provided information about themselves like name, contacts and a minibio (the problem I'm here to solve)
The text_frame, created with values of height and width, must fit the slide but must a contain all lenght of minibios, which is not happening.
In a long phase (>200 char, with font size 12) it exceeds the size of the text box and get "out" of the slide, so, in presentation mode or a PDF file, the "overrun" of text is lost
Is there any way to confine the text to the shape/size of the text_frame? (extra help if the solution wont change font size)
Just found one parameter that helped to find the answer
When creating a text_box object with slides.shapes.add_textbox() and adding a text_frame to it, the text_frame.word_wrap = True limits the text to be contained inside the dimentions of the text_box
The code shows it better
# creates text box with add_textbox(left, top, width, height)
txBox = slide.shapes.add_textbox(Cm(16),Cm(5),Cm(17),Cm(13))
tf = txBox.text_frame
tf.word_wrap = True
Before word_wrap parameter
After word_wrap parameter
The short answer is "No". PowerPoint is a page-layout environment, and much like the front page of a newspaper, text "story" content needs to be trimmed to fit the allotted space.
We're perhaps not used to this because word-processing, spreadsheet, and web-page content is "flowed" into a (practically) unlimited space, but the area of a PowerPoint slide is quite finite. Also, using it for large text blocks is somewhat of an off-label use. There is a certain amount of flexibility provided by reducing the font size, but not as much as one might expect. Even accommodating 20% additional text requires what appears as a pretty radical change in font size.
I've encountered this problem again and again, and the only solution I have ever seen work reliably is hand-curating the content to fit.
python-pptx has one experimental feature to address this but its operation has never been very satisfactory and it's tricky to get working. https://python-pptx.readthedocs.io/en/latest/api/text.html#pptx.text.text.TextFrame.fit_text
The business of fitting text is the role of a rendering engine, which python-pptx is not.

2-dimensional bin-packing in Excel

I’m trying to find a solution for the 2-dimensional packing problem using Excel (Formulas, Solver, VBA).
But apart from finding said solution, I would like to bring back this topic as base for discussion, because I realized during my extended web-searches that this problem (or variations of it) creates headaches for many people – novice and professional users.
The explanation for my problem:
I am trying to fit rectangular packages in rectangular containers. Usually there is one larger box and 2-5 smaller boxes to ship.
On average, there is still capacity of 30-50% left in the containers, so I want to calculate how many additional standardized boxes would fit in this free space to fill up the container.
There are no constraints, as long as the boxes fit into the container.
Height and weight are irrelevant.
The Boxes can be rotated by 90°.
One 40’ container is 1203cm long and 233cm wide.
The standardized boxes are 85cm x 70cm
The other boxes have different sizes.
I checked bin-packing algorithms but as of now I was not able to implement any solution in excel. I’d prefer a way to calculate this using Excel Solver or VBA, but my VBA-programming knowledge is limited.
The knapsack problem does not apply here in my opinion, although it is mentioned many times in this context.
In my case, I would be happy with a solution giving me something like: “You can fit at least x additional Boxes in the container”. Some inaccuracy does not matter – meaning up to 25% less boxes than possible. Too much boxes, on the other hand, are a no-go.
Now, do you guys have any idea how to get started here or even accomplish this? Maybe there is even a super-simple approximation I don’t know of?
Thanks!
UPDATE
After quite some time, I finally found some hours to get into this problem again.
I read Erwin Kalvelagen ‘s Blogposts and some papers on bin packing algorithms.
Also, the solver option is off the table.
I decided to go for a Bottom-Left-Algorithm (BLT) with some restraints (not just greedy).
Quick explanation of the BLT-Algorithm: Each box is placed in the bottom-most and left-most possible position in a given area (container). When a box is placed, it creates two new “corners” where the remaining boxes can be placed. Initially, the boxes are sorted by length (to start with the longest box) and place them in a 2-dimensional array. Then the starting point will be set in an Array (x, y coordinates) – the first coordinates are obviously 0, 0 as we start in an empty container. Then the algorithm would try to place the first box in the bottom-left corner with coordinates 0, 0 – which of course works perfectly. Then the starting cords would be replaced by the coords of one of the new corners and the coords of the other corner will be added to C. this would loop until all non-standard boxes are loaded. Then the algorithm would add standardized boxes if possible (and count them). The loop would end, if adding more boxes is not possible anymore due to constraints.
The dimension of the non-standard boxes will be entered in a worksheet - one box per row. The dimensions of the container and the standardized boxes will be written there as well.
Constraints would be, that no box can overlap another and all boxes would have to inside the container. Although rotation is practically possible, it is not necessary to implement it in the code as I am trying to orient the packages along the container.
Here is some pseudo code of the BLT-Algorithm I found:
**Procedure BLF(width, height,maxWidth)**
begin
initialize the arrays x and y
initialize the list and add the null point
for all rectangles
initialize choosePoint as impossible
while choosePoint is impossible and j < length of list
if the rectangle could be placed in a specific point
choose the point
endif
endwhile
if choosePoint is possible
update the arrays x and y
remove the point from the position choosePoint
from list
add the points (xi+width,yi),(xi,yi+height) to the points list
else
if (width > maxWidth) the problem has no solution
else xi = 0 and yi = max(heightk + yk)
where k 2 {1, . . . , i − 1}
endif
endif
endfor
solutions: the arrays x and y with (xi, yi)
the coordinates of rectangle i
end
Now, although I know a lot (like really A LOT) more about packing algorithms I am still not very experienced with VBA. Especially not with implementing algorithms.
So again I would be happy for any help you can give me to get started with the implementation.
So I started off with this (I know it’s really nothing, but I find it quite difficult):
Sub BLT1()
Dim Boxes As Variant, i As Integer, j As Integer ‘’Boxes dimensions
Dim Cntnr As Variant, a As Integer, b As Integer ‘’Container dimensions
Dim BLPoints As Variant ‘’Array with coordinates of bottom-left corners
Boxes = Range("B11:C15")
Cntnr = Range("D2:E2")
‘’Now I would like to add the first coordinates (0, 0) to the BLPoints
‘’Then I want to pick the first box and fit it in the container at the (0, 0) coordinates
‘’Then I want to update the BLPoints array with the new coordinates
…
End Sub
I’m looking forward to any constructive feedback and advice!
This is not a very easy problem. Some possible approaches are:
A MIP (Mixed Integer Programming) Model. The most complex part are the no-overlap constraint. For each box in the container we need to make sure it does not occupy space used by another box. The MIP approach has the advantage that we can find optimal solutions, or very good solutions with an indication how much we are away from a possible best solution (i.e. an indication of the quality of the solution).
A constraint programming model. Similar to the MIP model, but some constructs are easier to handle (i.e. the OR construct needed to formulate the no-overlap constraints).
A heuristic or meta-heuristic approach.
I implemented quickly a MIP model and it turns out you can get optimal or near-optimal solutions quite quickly. The solution below was found in less than a minute using a commercial MIP solver:
The yellow boxes are the required non-standard boxes and the blue ones are the optional standard boxes.
See here for more information about these no-overlap constraints. Here are the no-overlap constraints for this problem.

SSRS line chart

I have one question to the line chart.
I would like to create a line chart, which values are given. It should look like this chart here:
My question is, how can I implement this. I tried to put it as a stripline in the chart but it only shows a horizontal line without this steps at the beginning.
How can I create this line chart like in the picture above?
can I put into this:
the values.
Striplines are intended to display just a line across the chart, or varying width, height, to demonstrate an area... from MSDN
Strip lines, or strips, are horizontal or vertical ranges that shade the background of the chart in regular or custom intervals
To get the behaviour (I think) you require you can add a new series to the data you are returning with each of those datapoints. Irrespective of what other data you are charting, you can change the type of this series to Line Chart, and change the order of the series on teh chart to make it uppoermost.
Without further information - such as the data you are tyrying to superimpose this on - it's hard to advise further.

Changing line transparency of a series without affecting marker transparency in Excel VBA

I am writing a macro in VBA for excel in which I would like to change the transparency of the lines connecting markers in a series but leave the transparency of the markers in the series the same.
To specify: the chart is a scatter plot. I would like the markers for a series to be opaque/zero transparency and for the lines in the series to be 75% transparent.
I have adjsuted the transparency of the lines by using
myseries.format.line.transparency = 0.75
but this changes the marker transparency as well.
does anyone know of a way I can change the transparency of the two separately? I imagine there is a member/property to do what I want, but I cannot find it.
thanks in advance for any help!
This answer isn't going to make you very happy.
I've looked into this before and the information i've gotten is that this simply isn't a parameter that you can specify through VBA. It looks like you can access marker style, size, background color and foreground color, and that's about it.
Maybe MS didn't think anyone would ever want to mess with that.
One thing you could try is applying a custom chart format, but if you have variable numbers and/or orders of series then that may not work.
mychart.ApplyChartTemplate ("filepath\filename.crtx")
Something like that, where mychart is already set equal to the chart you want to format.
Again, maybe not of any use to you, best i could think of.
You guys didn't dig hard enough.
SeriesCollection(i).Format.Line.Transparency
will work if the SeriesObject is in a certain state. The original 'automatic' line style state prevents this vba from doing anything at first, but if you simply precede it by setting certain other properties on the line format first, then the transparency will take. The following worked for me:
For Each obj In myChart.SeriesCollection
obj.Format.Line.DashStyle = 1
obj.Format.Line.Transparency = 0.65
Next obj
DashStyle = 1 sets the line style to 'Solid' (as opposed to dashed, dotted, etc.) and has the side effect of freeing up the series format to have the transparency set. I don't know for sure why it works, but it does.
Sorry, my mistake. I read the question slightly wrong.
I find that if I start the line with no markers, then turning transparency separately doesn't turn the markers on and off.
Try this:
activechart.SeriesCollection(1).format.fill.transparency=0.5

Eliminate stray whitespace between textboxes on a report

I have 4 stacked textboxes in the body of an SSRS report and am getting a stray space / extra line between textboxes 3 & 4.
This is for an address block - name / title / email / website. Can't put it in a single textbox with intervening vbcrlf tokens because the email and website are links. I've tried formatting it to remove vertical spacing; also calculated the exact position by taking top + height to calculate the position. And of course I've tried positioning it so there are exactly 0 pixels between the text boxes. If I reverse the position of #3 & #4 the rendering looks the same so it isn't stray formatting characters in the data fields.
The solution is to wrap the stacked boxes in a rectangle.
I had this problem as well. It blew my mind until I started over on another part of the form. The new boxes worked perfectly until I moved them to the right of another set of text boxes which had some word wrap in them. I realized the wordwrapped boxes were directly related to the gaps I was seeing the set of textboxes to the right. I guess there's some kind of poor markup going on that tries to line things up horizontally and enclosing the set of textboxes in a rectangle protects them from it.
good idea on putting the info into a table - jumping off that idea - I'm going to construct a dynamic string in my query and output the dynamic string into a textbox. thank you for the idea, I don't know why I didn't think to do that.
Simpler thing is to just check text alignment - the default is "default" which appears to be centered. Changing the text box to the right to "left" fixed this problem for me.
Reduce padding property of the textbox.
Once dragging the textbox one closer to the other the tooltip shows convergence points between two textboxes - make tooltip show 0 points
it is best I could do to control the spacing