I am trying to write a VBA program for Autocad, and one of its function has to allow the user to select an entity in Autocad and scale it none uniformly. Currently i see offset and scaleentity method, but as far as i can tell, they are both uniform resizing.
My current code use selectionSets, AcadEntity and selectOnScreen to accomplish the target selection. So is there any VBA code to scale the selected entity none uniformly?
While it is not possible to scale entities non-uniformly in the AutoCAD designer itself, I wonder if it could by any API at all. It ís however possible for blocks.
So you might want to try to (temporarily) convert the entity to a block, insert the block with different X, Y (and Z) scales, explode it and delete the block reference again.
Related
I have a data set containing the following fields:
rack, rack_type, box_number, box_label, row, column
Each rack in the real world is basically a 2D grid with cells, each cell containing an object(a small box in this case). Each box will be associated with a specific position in the rack based on row and column. The size of the grid (number of rows/columns) is different based on rack_type
Is there a way to create a visual representation of these racks from the data supplied above? Specifically, I am looking to create a grid (as if you were looking at it in real life) where each cell shows some text--box_number and box_label in this case. I've been searching for hours on Google to no avail and I don't know if I'm even asking the question correctly. From what I can tell, the normal report/form features in Access do not support such a configuration of data. I'm wondering if there is some VBA solution, since I have some experience with VBA in Excel. Please let me know if this is incomprehensible gibberish.
If your racks has a finite maximum number of boxes in any configuration then you might consider this solution:
Let's say that any of your racks contains at most R boxes
create a form F
open F and add to it R text boxes B (they are not linked to anything)
save the form
now in VBA, on loading a rack you can iterate on each box and use some code to position each each of them on the form, show or hide it, and finally set its size!
Basically you've added to your form more boxes than a typical rack configuration would normally need, and by doing so you can hide some of them when not needed. You have this limit because you cannot create and add at runtime new text boxes to a form in VBA (it should work for reports too).
Note that you could use also other types of objects, text boxes are useful if you want to edit the text inside of them, otherwise you could use a label or anything that suits your needs the most (combo box... for example).
Basic methods that you might want to look at:
cell1.Height = 100
cell1.Visible = Not cell1.Visible
cell1.Move Left:=0, Top:=0, Width:=400, Height:=3000
Anyhow if you get more in details, by giving some examples of your racks we might be able to come with a more detailed solution.
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.
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.
The Visio Page object's SetFormulas and GetResults methods requires an array containing ShapeID,Section,Row,Column, in order to batch read/write from/to the shapesheet.
However, I find that in drawings with a lot of shapes, after adding and deleting shapes, Visio's shape ID's cross over the short integer limit of 32768. It seems Visio keeps a short integer ID property on shapes called ID16, but passing the ID16 into that ShapeID,Section,Row,Column array does not seem to work, and raises an 'Unexpected End of File' error.
Is it possible somehow to use the SetFormulas and GetResults methods on drawings where shape ID's have crossed over the short integer limit? Or is there a way to 'restack' shape ID's in a drawing such that, as long as there are less than 32768 shapes in the page, then all the ID's will be below the limit? I know that copying all the shapes into a new drawing will buy some time, but the issue could quickly recur after adding/removing shapes from the page, which my software does a lot of.
The only other alternative I can think of is to capture cases where the shape ID has exceeded the short integer limit, and revert to routines that do operations cell by cell and shape by shape, rather than in a single batch.
I fear there is no solution for this, Microsoft needs to create Int32 versions of SetResults/GetResults/SetFormulas/Getformulas/DropMany.
As PC's have become a lot faster these days it becomes easier to create huge Visio diagrams.
Rerendering a diagram to a new page does help to win you some time, but a 16 bits Shape ID (really a 15 bit limitation) is kind of silly in 2021!
When using methods of selecting text and restoring selected text in a page, I have found that running execCommand('insertHTML... inbetween causes the stored selection to break.
This is a sample of how the text is selected and restored.
// Get Selection
var sel = window.getSelection().getRangeAt(0);
// Clear Selections
window.getSelection().removeAllRanges();
// Restore Selection
window.getSelection().addRange(sel)
This works fine, however once you run execCommand('insertHTML.. the selections endOffset sets itself to the same value as the selections startOffset
Is there a reason for this? More importantly is there a way round this?
A full example of the bug, complete with some basic console logging can be seen here.
http://jsfiddle.net/blowsie/Y8pJ7/
The objective of this fiddle is to select text , transform it to uppercase and then reselect the text.
How best to save and restore the selection really depends on what you're doing. For your specific example, where existing text is just having its case transformed, I'd suggest a character index-based approach, such as https://stackoverflow.com/a/5596688/96100 (although that answer requires Rangy, but can be trivially changed not to require it: http://jsfiddle.net/Y8pJ7/8).
For some other cases, a better approach is to use invisible marker elements at the start and end of the selection, which is the approach taken by the selection save/restore module of Rangy (disclosure: I am Rangy's author).
UPDATE 18 June 2012
Rangy now has character offset-based save and restore of selections and ranges via a new TextRange module (demo).