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.
Related
In Outlook 2010 I have a UserForm with a ListBox.
This ListBox has 4 columns where I show a list of attachments (the columns "File-Name", "File-Type", "File-Size" and "Target-Directory".
Unfortunately the ListBox is restricted in layout functionality, the user can not adjust the column width at runtime (so I have to specify the width of the columns by design).
Because the file path can be quiet long, I set the width of the last column to 999 Pt.
So my ListBox has a horizontal scrollbar.
I want to have the following layout changes to my ListBox:
Add column headers
Change the alignment of a column to right-aligned
Optional: allow the user to sort the list by any column
Optional: allow the user to sort change the width of any column
Optional: show a grid in the ListBox
For 1. I found some answers that this is very complicated and I should use static labels above the list instead.
This is not possible, because my ListBox can be scrolled horizontally.
Is the ListBox really so restricted or is #1 and #2 possible somehow?
I know that there are foreign components available, but I am not allowed to buy any component.
And my solution should work at my colleagues too, so they would also have to install these components.
I have been experimenting with possible solutions to your problem. I think I have taken the listbox approach as far as it will go so I will share what I have discovered.
I can find nothing on the web to suggest that anyone believes you can have listbox column headers without using property RowSource. To use RowSource, you set it to an Excel range.
I got Outlook to create an Excel workbook and to write some data to it. Unfortunately, I could not find any way of getting an Outlook user form to access an Excel range. The syntax for setting RowSource is:
ListBox1.RowSource = "Emails!A2:D20"
This is not the standard syntax for a range and I have failed to discover any method of extending it to include a workbook name.
Jonah_Hess describes an interesting approach in https://stackoverflow.com/a/43381634/973283. He has two list boxes. One is a one-line listbox that contains the headings and the other contains the data. The two listboxes are set to the same number of columns with the same widths. This gives an attractive appearance but if you scroll the data listbox, the headings listbox does not scroll with it. This is not really any different from placing labels above a single listbox.
I tried putting the headings and the data list boxes in a frame and scrolling the frame but could not get it to work. I have used frames with VB user forms but the functionality is very different so there are no lessons learnt that I could bring to a VBA user form. Perhaps someone more familiar with VBA frames could get this approach to work.
I gave up trying to get a solution in Outlook. An Excel macro can access Outlook data so I tried that approach.
I created a macro-enabled workbook. Within it, I have two forms both of which fill the screen to conceal the worksheet. The first form just says: “Please wait while I load data from Outlook”. I am not clear about the data on your form so I imported selected details from a folder full of junk emails which I wrote to a worksheet. I sized the columns for the list box to match those for the worksheet. The result was:
The text is a little small but I think it is readable. The listbox at the bottom allows me to select emails for different periods. Long ago I had problems with RowSource which meant I could change the values in the range but I could not change the size of the range. I have either managed to avoid that problem today or it was a bug that has been fixed.
You can see that the headings are displayed. The columns are a little wide but I consider them to be a reasonable first approximation. Options to change the widths would be easy to implement.
The changes you ask for:
Add column headers. Done
Change the alignment of a column to right-aligned. Possible but difficult. You would need to pad the text with an appropriate number of leading spaces.
Optional: allow the user to sort the list by any column. The data is in a worksheet so easy.
Optional: allow the user to change the width of any column. I have set the column widths at runtime to show it is possible.
Optional: show a grid in the ListBox. Not possible.
If the above is interesting, I could show you all my code and instruct you on creating the forms so you could duplicate my experiment. Alternately, I could just explain: how I imported the Outlook data to Excel, how I included the column headings and how I set the column widths.
I cannot find anything to suggest that anything better can be achieved with listboxes.
An alternative approach is to use a grid of labels. This can give an attractive appearance and one or more columns could be right-aligned. Using the Controls property of the user form, you can treat the grid as a two-dimensional array. I have used this technique long ago and found it attractive and not particularly difficult.
In order to set the alignment of a specific column to the right, trying the opposite way might help you:
Set TextAlign attribute of the listbox to "3-fmTextAlignRight".
Add spaces at the END of the each data in the column of sourcearray, which you want to align LEFT. The number of added spaces should be so large as to exceed the width of the column in which the data appears. You don't have to mind whether the number fits to the columnwidth (overflown spaces do no harm). You may prefer to use & String(30, " ") instead (30 is just for example) .
If added spaces seem to be wholly ignored (i.e. data appear right-aligned only), further add any single character (such as "_") at the end of the spaces.
This is a cosmetic solution, but works when seeing left-aligned figures is too annoying.
After doing the above, please be careful when selecting from the list (trimming the added spaces, keeping BoundColumn data intact, etc.).
This trick works for both Excel and Outlook (not sure for other applications).
Test result in Outlook VBA (...trailing 50 spaces are added to data in column 1 and 4.)
Hope this helps.
I don't know anything about code. I work with e-learnings in Storyline 3. I sometimes localize these e-learnings and use the translation tool in Articulate which basically exports an MS Word file. Sometimes the target languages are longer and I need to decrease the font size by percentage for the whole document. Usually, there are at least 3 different font sizes that I need to decrease accordingly. I am wan to develop a macro that I will use for multiple documents.
I couldn't find a way to do this by percentage, but looks like the Shrink or Grow Methods will do the work! I found this code in the reference page but looks like it works only for a selected object. The issue is that the exported MS Word file is in a table with each text box in the storyline separated to a cell. When I select the whole table it does not work.
If Selection.Type = wdSelectionNormal Then
Selection.Font.Grow
Else
MsgBox "You need to select some text."
End If
Could you please help me and let me know if this would be possible for the whole document, or the selected table? It would be very much appreciated. Thanks in advance.
It is unclear from your question whether the table in the Word document contains the actual text boxes or just the text they contain.
If it is just the text then Shrink may work. I tested this on a document with a single table containing only text:
ActiveDocument.Range.Font.Shrink
Possible stupid question here...
But is it possible in MS-Access to programmatically manipulate text label captions in such a way that that a different caption will appear in the header of each report section?
Ie., The design view shows a text label object in the GroupLevel zero header, with a default caption of "blah"....but upon execution of a Report_Load() sub, the actual text displayed is different for each section in the report? Say, simply "Section 1", "Section 2', "Section 3" and so on?
My suspicion is that this is not possible, but just wondering if anyone has some creative ideas how to make it work.
I realize that there are other/better ways of accomplishing the same thing...but is such a thing possible using VBA and Label objects specifically (at the moment, this is an external constraint and one that I cant change).
EDIT: https://drive.google.com/open?id=1PID58qMyp_rNxv9tsQk38-Co9sDOFgzY
EDIT 2: Original post specifically designated LABELS as the only object for an acceptable solution. Edit to include LABELS and TEXT BOXES...which of course makes the question nearly trivial. Apologies to #peakpeak for my lack of clarity!
You can change the caption with
Me.<name of header>.Caption = "whatever"
Select Properties for the header in design view and find out and/or change the Name property. Me assumes that the VBA code is located under Microsoft Access Class Objects in the form you want to manipulate.
Actually, thank you for your help, but I have found something that appears to function as a decent work-around within the constraints I described above. Strictly speaking, this does not satisfy the terms of the question as originally asked (-1 to me for lack of clarity, and apologies to #peakpeak, who admittedly had essentially zero chance of answering this question as asked), but it this is close enough that it solves my immediate problem:
Change the object intended to contain my dynamic text from a label to a text box (duh!), keep all formatting settings, etc. the same so that the graphical presentation is unchanged.
Set the Control Source of the new text box to a public function, where the argument of the function is the name of a relevant field in the underlying query ("tName" in the linked example), so that the dynamic text box has a control source "=GetText([tName])" and the GetText() function is defined in the appropriate module for the report, and defines the text as desired, e.g.:
GetText(tName as String) as string
SELECT Case tName
Case "Albert"
GetText = "Section 1"
Case "Barry"
GetText = "Section 2"
Case Else
GetText = "Section 3"
'and so on
End Select
`
End Function
I am trying to automate a repetitive task in the SAP GUI. I need to search for an order number, select the row that the order number is in and then click a button to complete the task. I have recorded a macro which gives me:
session.findById("wnd[0]").maximize
session.findById("wnd[0]/usr/cntlCONTAINER/shellcont/shell").pressToolbarButton "&FIND"
session.findById("wnd[1]/usr/txtGS_SEARCH-VALUE").text = "4521305207"
session.findById("wnd[1]/usr/txtGS_SEARCH-VALUE").caretPosition = 10
session.findById("wnd[1]/tbar[0]/btn[0]").press
session.findById("wnd[1]/tbar[0]/btn[12]").press
session.findById("wnd[0]/usr/cntlCONTAINER/shellcont/shell").currentCellColumn = ""
session.findById("wnd[0]/usr/cntlCONTAINER/shellcont/shell").selectedRows = "2894"
session.findById("wnd[0]/tbar[1]/btn[14]").press
session.findById("wnd[1]/usr/chk[1,6]").selected = true
The line:
session.findById("wnd[1]/usr/txtGS_SEARCH-VALUE").text = "4521305207"
Corresponds to the order I want to search, but if I change this value it still tries to process the same order that the macro was recorded on, I'm assuming because of the line:
session.findById("wnd[0]/usr/cntlCONTAINER/shellcont/shell").selectedRows = "2894"
Does anyone know how I would go about finding the number of the row which corresponds to the outcome of the SEARCH-VALUE and then using that as the .selectedRows = ""?
First of all I'd really recommend you add a reference to the native SAP library. Go to your VBA Editor, click Tools, then References, then Browse, and find this file: "C:\Program Files\SAP\FrontEnd\SAPgui\sapfewse.ocx". Add it, and now you'll have types and libraries and coding for SAP will be a lot easier, safer, and slightly faster (Variant types in VBA impose a tiny overhead that in this case is totally unnecessary). Get familiar with this new library if you are going to do any SAP scripting more than once.
Second, about this problem, what you have is a shell, of type GuiShell, which inherits from GuiGridView. GuiGridView looks like a table, a classic Excel-like set of rows and columns. In your transaction, is showing you a big list of orders, in which you go click the "Find" button, put the order you're looking for, and then close the Search Window. Back to your (Grid)Shell, this cell has been selected (Grid has properties SelectedCells, SelectedRows, SelectedColumns that get all set when you go find something), but then you go and modify the value of SelectedRows to a specific one.
So yeah, upon find, a cell has been selected, so all you need is to query its row and then assign it where you need:
Dim numrRow As Long
numrRow = session.FindById("wnd[0]/usr/cntlGRID1/shellcont/shell").CurrentCellRow
session.FindById("wnd[0]/usr/cntlGRID1/shellcont/shell").SelectedRows = numrRow
where "thisShell" is however you do to find a reference to the Shell (session.findByID("blabla") for example, but I'd advise to reduce all the findByID's, they're very slow and type-unsafe).
If you need help about this SAP libraries, feel free to maybe make some new post and ping me on the comments about it.
I'd like to be able to create a page element which I can feed text and it will form itself into the preferred layout. For instance:
{MACRO DocumentIntro("Introduction to Business Studies", "FP015", "Teachers' Guide")}
with that as a field, the output should be a line, the first two strings a certain size and font, centred, another line and then the third string fonted, sized and centred.
I know that's sort of TeX-like and perhaps beyond the scope of VBA, but if anyone's got any idea how it might be possible, please tell!
EDIT:
Ok, if I put the required information into Keyword, as part of the document properties, with some kind of unique separator, then that gets that info in, and the info will be unique to each document. Next one puts a bookmark where the stuff is going to be displayed. Then one creates an AutoOpen macro that goes to that bookmark, pulls the relevants out of the keywords, and forms the text appropriately into the bookmark's .Selection.
Is that feasible?
You're certainly on the right track here for a coding solution. However, there is a simpler way with no code - this is the type of scenario that Content Controls in Word 2007 were built for and with Fields/Properties, you can bind to content controls (CC). These CC can hold styles (like centered, bold, etc.). No VBA required.
The very easiest thing to do is to pick 3 built-in document properties that you will always want these to be. For example, "Title" could be your first string, "Subject" your second string and "Keywords" your third. Then, just go to the Insert ribbon, Quick Parts, Document Properties and insert, place and format those how you like. Then go to Word's start button (the orb thingy) and then under Prepare choose Properties. Here you can type, for example "Introduction to Business Studies", into the Title box and then just deselect it somehow (like click in another box). The Content Control for Title will be filled in automatically with your text.
If you want to use this for multiple files, just create this file as a .dotx (after CC insertion/placement/formatting and before updating the Document Properties' text). Then every time all you'll have to do is set these three properties with each new file.
Well, yes, it did turn out to be feasible.
Sub autoopen()
Dim sKeywords As String
sKeywords = ActiveDocument.BuiltInDocumentProperties(4)
ActiveDocument.Bookmarks("foo").Select
Selection.Text = sKeywords
End Sub
Okay, I have some filling out to do, but at least the guts of it are there.