Jump to content

BAleiHi

Members
  • Posts

    33
  • Joined

  • Last visited

Everything posted by BAleiHi

  1. Thank you comment for your patience and ideas. I see that I was careless writing the post and not using the FMP syntax..will be more careful next time. But to the main point, your suggestion to remove the cmd.exe /C part seems to have done the trick. It tripped me up because when I set the tag with a literal text string "test me" it worked fine. But with the more complex replacement syntax, it failed. The /C after the command is a switch presumably implemented inside FMP's native SendEvent to say whether to return and close the window or leave the window open. I'm not clear on why BE_ExecuteSystemCommand would behave differently for the two cases, but I can move forward!
  2. Thanks for the hints...Turns out the issue is not with the set field vs. set variable. Both behave the same. It could certainly be with my syntax, but if so, it's not clear why. I have been anything but careless and I bristle at the suggestion (after hours of testing to get it correct). You say the posted code is invalid. If so, please specify what you think is invalid about it...that may be the issue (BTW, I use <> to show a variable file path - it's not literal text.) Here is exactly what works in cmd,: exiftool -overwrite_original "-model<${imagedescription;}" "G:/My Drive/IMG_2191.jpg" Here is exactly what returns file not found in BE: cmd.exe /C exiftool -overwrite_original "-model<${imagedescription;}" "G:/My Drive/IMG_2191.jpg" I do note that there is a space in the path name that doesn't bother SendEvent but might trip up BE. So I tried a path with no spaces. Still no luck. BE seems to be doing something with the ", <. $. {, or ; in the command line that SendEvent does not. Any ideas? Everything works when I set the tag to a literal text string so I know that the image file is OK. I got the replace and indirection syntax straight from Phil Harvey along with double quotes, curly brackets and the semicolon (a trick to remove illegal windows filename characters from a string. But he's not a FM or BE expert... If you see a flaw, I'd love to know what it is. Thanks!
  3. Headaches abound trying to implement a wait loop. So going back to BaseElements, perhaps you can shed some light there. Since BE are only functions that are accessible through a calculation, I tried Set Variable( $test, BE_ExecuteSystemCommand, $cmd). [An aside: what's the preferred way to call a BE function when I don't really care about what it returns?] The $cmd I constructed works using SendEvent as long as I wait long enough. It's cmd.exe /C exiftool -overwrite_original "-model<${imagedescription;}" "<fullpath to filename>" Any insights greatly appreciated.
  4. I've figured out how to use FMP to write EXIF data to a jpg file in Windows and have written a "SetEXIFTag" script that relies on FMPs SendEvent function to execute. The code is below. The parameter tagToSet will be overwritten by either direct text or by the contents of another EXIF field, depending on the switch setFromTag. The problem that I now face is that the command sent to Windows takes some amount of time to complete and SendEvent returns before it's done. The FMP code continues and takes certain actions that are incorrect because the tag hasn't been changed by the time they execute. Apparently Mac has a SendEvent option "Wait for event to complete before returning" which is not available in Windows. Ugh. My hypothetical workaround for this would be to pass in the original value of the tagToSet, then add a loop at the end that reads it until it has changed. But that requires that I can read an EXIF tag into FMP. Does anyone know how to do that? The only way I know would be to pass in the Container object that contains the file and use GetContainerAttribute. This, of course, would limit the user to tags that GetContainerAttribute supports. In my case, that will work but I'm hoping there's another solution. I did try BaseElements' BE_ExecuteSystemCommand, which is supposed to wait for completion by default, but couldn't get it to do anything. I'd just as soon avoid the plugin if possible. Thanks for your thoughts. Platform: Windows 11, FM 21 (2024), EXIFTools 12.85, single machine (no Server) #------------------------------------------------------------------------------------------------------------------ # SetEXIFTag # Sets an EXIF tag to the value passed in. Parameters: # > filename - the full path and name of the image file to edit. Expected to be a JOG file. # > tagtoSet - name of the EXIF tag to set. Not preceded by a - # > newValue - the text string to set the tag to. # > overWriteOriginal (Optional) - Yes/<>0 to overwrite the original file, no to save a copy of it. Default is Yes/<>0 (overwrite!) # > setFromTag (Optional)- Boolean. Yes/<>0 to interpret newValue as another tagname from which to extract the newValue to write. # No to interpret it as direct text. Default is No/0 (direct text). # Examples: # Perform Script [ By name "SetEXIFTag"; List("C:/users/blah/IMG_2304.jpg"; "model";"213-23-This is a test") ] # Perform Script [ By name "SetEXIFTag"; List("C:/users/blah/IMG_2304.jpg"; "model";"imagedescription");;1 ] #------------------------------------------------------------------------------------------------------------------ Set Variable [ $filename; Value:GetValue ( Get(ScriptParameter); 1)] Set Variable [ $tagToSet; Value:GetValue ( Get(ScriptParameter); 2)] Set Variable [ $newValue; Value:GetValue ( Get(ScriptParameter); 3)] Set Variable [ $overwriteOriginal; Value:If(IsEmpty(GetValue ( Get(ScriptParameter); 4));1;GetValue ( Get(ScriptParameter); 4))] Set Variable [ $setFromTag; Value:If(IsEmpty(GetValue ( Get(ScriptParameter); 5));0;GetValue ( Get(ScriptParameter); 5))] # Probably want some integrity checking here! If [ $setFromTag = True] # Set tag to the contents of another tag Set Variable [ $cmdToRun; Value:"cmd.exe /C exiftool "& If($overwriteOriginal=1;"-overwrite_original ";"")& "\"-model<${imagedescription;}\" \"" & $filename & "\"" ] Else # Set tag directly to entered text Set Variable [ $cmdToRun; Value:"cmd.exe /C exiftool "& If($overwriteOriginal=1;"-overwrite_original ";"")& "-"&$tagtoSet&"=\""&$newValue&"\" \"" & $filename & "\"" ] End If # Execute the FMP command Send Event [ open document/application; $cmdToRun ] Exit Script [ ]
  5. When I import photos into a Container using a script, there is no option to import a reference to the file only as there is in a separate dialog when I do this manually. How do I import a folder to a container field, using the reference only, within a script? Doh! Never mind. Just found it in the option when I specify "Folder". I'd swear that dialog didn't appear yesterday (or was that my mind that didn't appear yesterday?)
  6. Hello, I want to be able to read and write to the EXIF tag -imagedescrption in JPG files stored in a container by reference from within FM. It looks like FM natively supports only reading the data from a few tags - like filename, make, model, ... the options in GetContainerAttribute. I see a few plugin options - Trio, MBS (MonkeyBread), MediaManager but cant' tell easily from the documentation whether they can do this. There are other references in this FM plugin list but many seem stale. I've used Phil Harvey's EXIFTools some so maybe I could make use of that from within FM somehow? Has anybody done this in a while who can lead me to the best solution. Note that I'm a hobbyist (retired) working on a one-off solution for a nonprofit HOA. Thus I have a limited budget, and prefer shareware or open source solutions. Thanks so much. Platform: Windows 11, FM 21 (2024), single machine (no Server)
  7. Is there a way, even if it requires a plug-in, to get some more advanced features in the script editor. Specifically I really miss search and replace (or even just search!) and a horizontal (or vertical) split window to edit more efficiently. While I get that it's not a text editor, these features are so useful you'd think someone would have implemented them. Thanks.
  8. I did use page margins and page breaks but they don't really show where the breaks occur, presumably due to sliding? My current workaround seems to be fine and avoids having to have a script to manage the printing in two separate print steps per report with two separate layouts. I'm also not clear on how I would collate together the outputs, particularly on a batch job where I need to print 300-400 reports. But I definitely appreciate your sharing your approach and will use it if my current solution gets flaky with, say, a different printer setup or something.
  9. Thanks to both of you. I decided to go with Soren's approach - and was able to do it with only one layout, based on the Owner table. For the page to appear to break correctly I used a kludgy workaround. When there were more than two photos, the first page showed only a fraction of the top of the second page. So little that when I corrected each part size to the maximum for the page (712 pixels in my case) as Soren suggested and slid things as far down the second page as I could, the only thing showing on the first page is the border of the portal row. I fixed that by setting the format to no line. I was even able to slide the image container down within the portal row to give a little extra top border on the second page. Several hundred iterations I'm sure, but ultimate success. I get that FM is not a work processor, but geez can't they implement a more predictable and effective reporting/printing scheme. In previous solutions I have exported data to Excel simply to use its formatting and printing capabilities. Ughh!
  10. @comment, that helps and certainly makes the layout simpler to understand and manipulate. Unfortunately, there are also reports to print that do not have photos associated with them. Any way to handle that without doing separate layouts for the two cases?
  11. Hello, I have a layout that displays a homeowner inspection report. The first page should show a header (name, address, comments, etc. and two of a possible 8 photos of the home. The second page should show the subsequent 6 of a possible 8. I set the layout up with a Sub-summary by Lot at the top to show the lot specific info and the first two photos (two single row portals starting at the record 1 and record 2 of the linked PhotoList table respectively). Then I set up the Body with the other six photos, using 6 portals, starting at record 3-8 of the Photolist respectively. Here's the first page = Leading sub-summary: Here's the second page = Body: I've tried all kinds of combinations of part page breaks, sliding and hiding objects, resizing enclosing parts etc, but I can't for the life of me figure out how to set it up so I get one page if there are 0, one, or two images and two pages if there are 3 or more images with the page breaks in the right place. Rather than document everything I've tried and the current behavior, I figure I'll ask how to do it correctly. Any guidance would be greatly appreciated...
  12. Thank you, I ended up just using the If/multiple Else Ifs option (Case statement) to avoid the hassle of figuring out a more elegant way. It makes the code much more readable which is nice but I feel like I'm back in Coding 101 doing it that way. Oh well.
  13. Hello, I have a typical row/column portal with labels as column headers. I want to be able to click on a column header (a text grouped button) and pass the associated field name to a script that then sorts by that field. I don't see a "Sort Records" or Sort Records by Field" that supports a variable name for the field. I notice that Sort Records by Field will use the currently active field if no field is provided - but I can't figure out how to "activate" the field using a variable. I tried "Go To Object" where the variable is the Object name but I get an error [3] Command is unavailable. This seems like it should be easy and I can brute force it with a case type structure but that feels really clumsy. Anyone know a better approach? Thanks
  14. Wow, that's cool. I never considered brute force calculating the formatted text. I suppose I could write a custom function to support formatting rounded to a given number of decimals. I guess I'm spoiled and used to platforms that have that kind of functionality built in. For this one, however, I think the easiest solution is to use the field formatting with conditional visibility rather than the calculation. Not too bad! Thanks for the help
  15. Thank you Kaizentu. In this case the layout object is a button bar with a conditionally calculated title and there is no option to set the format of the object. I've gotten used to using that technique a lot to display conditional or calculated text. It's a great way to avoid creating another calculated field but seems to have this limitation. I went back to the workaround for this - two instances of the field superimposed, using "Hide object when" to display the relevant one. Any other option? Thanks
  16. I have a layout calculation that looks like: Round(If($$NoGPABump = 1;Classes::GPANoBump; Classes::GPABumped);2) In most instances, this rounds the appropriate value to 2 decimals and displays those two digits. But on occasion, it displays only one decimal as in this one: . Instead I want to see 4.20. If I round to, say, 4 decimals, it works properly: . Rounding to 3 digits gives 4.199. How do I get the trailing zero to show up? This seems to be consistent for all data that rounds to a last digit of zero. Is this a bug? Is there a workaround? Thanks,
  17. Thank you again Mr. V. Turns out my analysis of the situation was flawed in several respects. Your comments helped me try some other things and I realized that when I use InsertFile to get a filename and store it into a variable instead of into a container field, everything seems to work just fine - whether I'm in the hosted file or in a local copy of it. So I think I'm off the hook. I appreciate your help!
  18. Thank you, Mr. V, for the Troi tip - I'll look into that. Re: your second point, I apologize for inexact language - as a newcomer to server based solutions, I'm sure I'm confused in ways I don't even know about. Please allow me to try again. My solution is hosted on FMServer, but is opened by one of several machines running their own copy of FM17 Advanced. When I say I want to "run it on the server" I mean only that I'm running the server hosted version of the file from one of those machines. All those machines are networked and have access to a common directory that contains the Excel file that I want to import. I *also* have a copy of the solution on my local machine where I do most of the development, only uploading it to the server when the development version is stable. When I run the solution locally, the "Insert File" thing works fine...it's when I'm trying to run the hosted file that causes the problem since "Insert File" does not work. If I don't specify the filename in the import script step, the user can do it at run time, but has to do it three times. The only workaround I can think of is to hardcode the filename and pull the full path from a user profile table that is unique to each machine which feels very clumsy.
  19. Hi, My solution opens an Excel file and loops through 3 tabs in it, importing and processing the contents of each. What I really need to do is get the user to specify an Excel file (preferably by opening a script generated default directory and filtering to only Excel files...something I can't seem to get to happen) then, in a loop, import data from 3 separate tabs in the file (tab names are fixed but import mapping is different for the different tabs) and process that data. When I'm running locally I can get the input file name by using Insert File into a container to hold on to the file name and can set up the imports specifying the filename, tab, and import order for each import step. This seems like a really clumsy way to get a filename that can be accessed multiple times without repeated user input, but it seemed to be the only approach back when I wrote .V1 of this script (a couple years back). But it worked for a local database. Now I'm trying to run from FM Server where Insert File is not supported. So how do I do this? I'm running on Mac and Windows so any solution that involves plugins needs to work for either (seamlessly). Conceptually, this seems to be very simple ... get a filename and access it multiple times. But I'm tearing my hair out trying to make this work. Thoughts or guidance? Thanks
  20. I'm trying to arrange for "Insert File" to open in a particular folder (cross platform). It seems it will only go to a specific file that I fully specify. If the file doesn't exist, it seems to go to some other place (like the last folder or the documents folder). Any way to control this? Thanks
  21. I want a layout with a fixed header for every page across the whole page, a leading sub-summary across the whole page, then another leading sub-summary and a body that each span two flowing columns, then a trailing sub-summary across the whole page. From what I can tell, FM can only do the flowing two column thing in all the layout parts except the header and footer, not specific to particular layout parts. Any chance 16 or 17 have that feature? (I'm in 14). If not, any ideas for a workaround? Any way to get the contents of the header and footer to vary like a sub-summary? Any other possible workarounds? Thanks,
  22. I need to determine whether a variable exists as distinct from whether it is empty. From what i can tell, if i access a non-existent variable, it returns empty. If $$foo doesn't exist, IsEmpty($$foo) returns true. But If $$foo exists and is empty, then IsEmpty($$foo) also returns true. How can I distinguish an existing but empty $$foo from a non-existant $$foo? Thanks,
  23. Sorry for the confusion - I was trying to be concise. The Excel files are exported from the web site that hosts the system through which our teachers take attendance. I have a script that automates the export of these files into their default file names. I set up my browser to always save the files in a particular directory - that's the directory that, nominally, I am trying to access from the solution.
  24. Thanks David. This is a process that gets repeated a lot - every day, 7 files per day. Prompting for all of those files gets really tedious and the process is very repetitive so I want to avoid it. But your suggestion reminded me that I also have a user preferences table. I could store user specific paths in that. User can set that path...I think I'll try that.
  25. I have a student records solution into which I regularly want to import attendance data that's coming from Excel files. Each day's attendance is stored in 7 separate Excel files. The user populates the files, then runs a script to import and process them. When I was developing the solution on a stand alone machine I set up a table that contains the path and filenames of the 7 files that the script loops through. If I ever had to move to different paths or decided to change file names, I could just change the paths and names in the table. Fast forward to trying to implement this solution via FMServer (...FMServer newbie alert!). I figure I can just put those files....hmmm...where? On the server in the same directory as the solution? Problem is I don't want the users who populate the Excel files having access to that directory. So I decided to put them on a DropBox folder that's shared between the server and the users who will be populating the Excel files. But now I don't know what path to use to reference the files from the solution. Specifically, the .fmp12 file is in the root directory of the server as in <servername>/Databases/mysolution.fmp12. The files I need to access are physically located on a different machine than the server under it's DropBox folder as in <othermachine>/DropBox/DataSupport to which I have created a symlink on the server that makes that folder look like <servername>/DataSupport. How do I reference that location from the solution? Is it even possible to do so? If so, that would seem like a security risk. So then it occurred to me that these files shouldn't reside on the server, but rather on the clients. But then how do I reference the locations on the clients? The only client paths that I know how to identify reliably are from Get(DocumentsPath), Get(DesktopPath), Get(DesktopPath) and Get(PreferencesPath). Should I set up a preferences file of some sort that documents the necessary paths on the client machine(s)? I suspect someone is going to say that I should put the files in the container directory on the server and access them through containers in the solution. Can I set up the container directory to be a symlink to a Dropbox share? Is that the preferred solution for this kind of situation? Thanks for your thoughts and advice,
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.